【问题标题】:AS3 Socket/Server MMO CommunicationAS3 Socket/服务器 MMO 通信
【发布时间】:2010-11-27 21:41:29
【问题描述】:

我正在开发带有 c# 服务器的 Flash MMO。我有一个简单的套接字消息传递协议。当客户加入时,他会发出以下信息:

 "%|clientId|need"

并且位置更新如下:

 "$|clientId|xPosition|yPosition"

由于某种原因,这不起作用。我将所有头像存储在一个数组中,头像类只是扩展了movieclip。这应该将所有客户端添加到房间中,但它不起作用。有什么想法吗?

编辑:错误可能在上面的客户端代码中,我认为它与我将头像存储在数组中的方式有​​关。

这是我的代码:

id.text = String(Math.random());
import flash.net.Socket;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.utils.Dictionary;

var avatars:Array = new Array();

 var _socket:Socket = new Socket();
 _socket.addEventListener(ProgressEvent.SOCKET_DATA,socketData);
 _socket.addEventListener(Event.CONNECT,socketConnected);
 _socket.addEventListener(IOErrorEvent.IO_ERROR,socketError);



_socket.connect("192.168.1.4",8000);

function sendText(msg:String):void {
 if (_socket.connected) {
  _socket.writeUTFBytes(msg);
  _socket.flush();

 } else {

 }
}

function socketConnected(e:Event):void {
 chat.appendText("Connected. \n");
 sendText("%|" + id.text + "|need");
 //chat.scrollV = chat.maxScrollV;
}

function socketError(e:IOErrorEvent):void {
 chat.appendText("SYSTEM MSG:"+e.text+"\n");
 //chat.scrollV = chat.maxScrollV;
}

function socketData(e:ProgressEvent):void {
 var str:String = e.currentTarget.readUTFBytes(e.currentTarget.bytesAvailable);
 trace(str);
 //var xml:XML = new XML(str);
 chat.appendText(str + "\n");
 //[pos]|50|334
 if(str.search("$")){
  var positionArray = str.split("|");
  avatars[str[1]].x = str[2];
  avatars[str[1]].x = str[3];
 }
 if(str.search("%")){
  var miniArray = str.split("|");
  avatars[miniArray[1]] = new Avatar();
  addChild(avatars[miniArray[1]]);
  dump.text = miniArray[1];
 }

}



me.addEventListener(MouseEvent.MOUSE_DOWN, drag);
me.addEventListener(MouseEvent.MOUSE_UP, sDrag);

var timing:Boolean = false;
var t:Timer = new Timer(1);
t.addEventListener(TimerEvent.TIMER, tick);

function tick(e:TimerEvent){
 if(timing){
  sendText('$|'+id.text+'|'+me.x+'|'+me.y);
 }
 else{
 }
}

t.start();


function drag(e:MouseEvent){
 me.startDrag();
 timing = true;
}

function sDrag(e:MouseEvent){
 me.stopDrag();
 timing = false;
}

【问题讨论】:

  • 我没有看到您的打包代码,即您在哪里确保在解析消息之前完全到达。并将不属于当前数据包的部分消息保留在将来的数据包中使用。

标签: c# actionscript-3 sockets


【解决方案1】:

编辑:根据其他信息更改答案。

解决代码后您遇到了一些问题。首先是您使用 if(str.search)... $ 和 % 可以解析为正则表达式。此外,由于您的字符索引为 0,因此这些 if 可能不成立。最后,您使用的是 str[1] 而不是 positionArray[1] 等。下面是工作代码,在不使用套接字服务器的情况下进行了一些黑客测试。当您遇到此类问题时,可能会向您展示一些有关如何进行重点测试的技巧。

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;

    public class TestSocket extends Sprite
    {
        import flash.events.MouseEvent;
        import flash.events.TimerEvent;
        import flash.net.Socket;
        import flash.utils.Dictionary;
        import flash.utils.Timer;

        [Embed(source="assets/avatar.png")]
        private var Avatar:Class;

        private var avatars:Array = new Array();

        function TestSocket():void
        {
            socketSimulator(10);
        }


        function socketData(e:ProgressEvent):void {
            var str:String = e.currentTarget.readUTFBytes(e.currentTarget.bytesAvailable);
            trace(str);

            if(str.indexOf("$") >= 0){
                var positionArray = str.split("|");
                avatars[positionArray[1]].x = positionArray[2];
                avatars[positionArray[1]].x = positionArray[3];
            }
            if(str.indexOf("%") >= 0){
                var miniArray = str.split("|");
                avatars[miniArray[1]] = new Avatar();
                addChild(avatars[miniArray[1]]);
            }

        }


        /** Test Code **/
        private var _numClients;

        private function socketSimulator(numClients:int):void
        {
            _numClients = numClients; 

            var msg:String;

            while(--numClients >= 0)
            {
                msg = "%|" + numClients + "|need";
                sendFakeData(msg);
            }

            var timer:Timer = new Timer(500, 9999);
            timer.addEventListener(TimerEvent.TIMER, sendFakeMovement);
            timer.start();
        }

        private function sendFakeMovement(e:TimerEvent):void
        {
            var id:uint = Math.random() * _numClients;
            var x:Number = Math.random() * 1000;
            var y:Number = Math.random() * 1000;
            var msg:String = "$|"+id+"|"+x+"|"+y;

            sendFakeData(msg);
        }

        //This is just hacked test code, don't do this in production
        private function sendFakeData(msg:String):void
        {
            var e:MyProgressEvent = new MyProgressEvent(ProgressEvent.SOCKET_DATA);
            e.currentTarget = {
                readUTFBytes: function(bytes:int = 0):String
                {
                    return msg;
                }
            }

            socketData(e);
        }
    }
}
import flash.events.ProgressEvent;

class MyProgressEvent extends ProgressEvent
{
    private var _currentTarget:Object;

    public function set currentTarget(val:Object):void
    {
        _currentTarget = val;
    }

    override public function get currentTarget():Object
    {
        return _currentTarget;
    }

    function MyProgressEvent(type:String):void
    {
        super(type);
    }
}

【讨论】:

  • Flash 接收消息正常,我有一个显示所有消息的日志。我的服务器接收客户端的消息并将其发送给所有其他客户端。
【解决方案2】:

在您测试登录/注销/位置之前,请确保您的架构首先支持发送和接收数据,我的意思是,在前端发送一个字符串(“一些数据”)并检查您是否'真的在后端接收(“一些数据”)。恐怕您在客户端发送的字节顺序与服务器上的字节顺序不同,因此服务器会误解传入的数据。如果是这样,您需要在尝试处理传入消息之前将它们转换为合适的字节序。

【讨论】:

  • Flash 接收消息正常,我有一个显示所有消息的日志。我的服务器接收客户端的消息并将其发送给所有其他客户端。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多