我正在尝试使用NetStream在在线Flash多人游戏中的玩家之间传递数据。
我使用NetConnection类的事件调度,所以我知道我的客户端的当前状态。
例如,当我有一个“NetConnection.Connect.Success”时,我知道我可以开始使用NetStream类并将NetConnection对象传递给它。
一切都有道理并且运作正常。
但是,在收听NetStream.Connect.Success事件时遇到了问题。似乎这个事件被无缘无故地多次激活,它是第一次当两个用户相互连接时被触发,这很好,我可以看到他们的farID并将它传递给另一个对等体,一切正常。
然而,在那些对等体之间的第一次连接之后,没有明显的原因会激发3或4个NetStream.Connect.Success。这不仅令我烦恼,因为我不明白为什么会发生这种情况,而且还会打破我的“基于事件”的架构,以确定接下来会发生什么事件。
我可以毫无问题地发送和接收消息,直到我得到NetStream.Connect.Closed,这通常会在几秒钟之后发生。有时候我从来没有得到过一个封闭的事件,有时当我得到一个,我仍然可以发送和接收消息,这就像另一个连接被关闭而不是我现在正在使用的连接。
就像你看到的那样,它真的很乱,我不知道我是否犯了一些错误,或者整个事件系统设计得不好。
我不知道我做得对的另一件事是,我将发送流和接收流的客户端属性分配给“this”,不确定是否可以,但因为它“有效”。我猜这不是这种奇怪行为的原因。
(amfphp服务,它的作用是交换farID)
这是我的代码,这是一个非常简单的聊天应用程序:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="700" height="700"
>
<s:VGroup width="100%">
<s:TextArea id="historyTxt" width="100%" verticalAlign="bottom" enabled="false"/>
<s:TextInput id="inputTxt" enter="sendMessage(event)"/>
</s:VGroup>
<s:Button id="joinBtn" x="250" y="300" width="200" height="100" label="JOIN" fontSize="20" click="init()"/>
<mx:Text id="nearIDTxT" x="10" y="647" text="nearID" alpha="0.7" fontStyle="italic"/>
<mx:Text id="farIDTxT" x="10" y="669" text="farID" alpha="0.5" fontStyle="italic"/>
<fx:Script>
<![CDATA[
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.NetStatusEvent;
import flash.events.StatusEvent;
import flash.geom.Point;
import flash.net.GroupSpecifier;
import flash.net.NetConnection;
import flash.net.NetGroup;
import flash.net.NetStream;
import flash.net.registerClassAlias;
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import flash.utils.Timer;
import flash.utils.getTimer;
private const SERVER:String = "rtmfp://p2p.rtmfp.net/";
private const DEVKEY:String = "cde41fe05bb01817e82e5398-2ab5d983d09f";
private const NAME:String = "Paul";
private static const BOT:int = 1;
private static const TOP:int = 0;
private var _groupSpecifier:GroupSpecifier;
private var _cirrusNc:NetConnection;
private var _amfphpNc:NetConnection;
private var _groupSpec:String;
private var seq:int = 0;
private var _user:String;
private var _status:String;
private var _sendStream:NetStream;
private var _receivingStream:NetStream;
private var _connected:Boolean;
public var res:Responder;
public function init():void
{
joinBtn.visible = false;
_status = "waiting";
_cirrusNc = new NetConnection();
_cirrusNc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
_cirrusNc.connect( SERVER + DEVKEY );
}
public function onResult(response:Object):void {
//here we ask if there is another player waiting to connect to someone
if(response == "waiting") {
//just wait
}
//if not:
else {
connectToPeer(response[1]);
}
}
public function sendMessage(e:Event):void {
_sendStream.send("handler", e.currentTarget.text);
e.currentTarget.text = "";
}
public function onFault(response:Object):void {
for (var i:* in response) {
trace(response[i]);
}
}
private function onNetStatus(event:NetStatusEvent):void {
switch(event.info.code){
case "NetConnection.Connect.Success":
trace(event.info.code);
nearIDTxT.text = _cirrusNc.nearID;
onCirrusConnect();
break;
case "NetStream.Play.Start":
trace(event.info.code);
break;
case "NetStream.Connect.Success":
trace(event.info.code);
if(!_connected){
_connected = true;
farIDTxT.text = event.info.stream.farID;
onPeerConnect(event.info.stream.farID);
}
default:
trace(event.info.code);
}
}
private function onCirrusConnect():void {
//connecting to amfphp
_amfphpNc = new NetConnection();
_amfphpNc.connect("http://localhost/Amfphp/");
res = new Responder(onResult, onFault);
_amfphpNc.call("Rendezvous.match", res, NAME, _cirrusNc.nearID);
//defining the send stream
_sendStream = new NetStream(_cirrusNc, NetStream.DIRECT_CONNECTIONS);
_sendStream.client = this;
_sendStream.publish("data");
}
private function connectToPeer(farID:String):void {
farIDTxT.text = farID;
//defining the receiving stream
_receivingStream = new NetStream(_cirrusNc, farID);
_receivingStream.client = this;
_receivingStream.play("data");
}
private function onPeerConnect(farID:String):void {
farIDTxT.text = farID;
//defining the receiving stream
_receivingStream = new NetStream(_cirrusNc, farID);
_receivingStream.client = this;
_receivingStream.play("data");
}
public function handler(message:String):void {
trace(message);
historyTxt.text = message;
}
]]>
</fx:Script>
</s:Application>