0

我正在尝试使用 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>
4

0 回答 0