AS3套接字/服务器MMO通信

时间:2010-11-27 21:41:30

标签: c# actionscript-3 sockets

我正在使用c#服务器进行Flash MMO。我有一个简单的套接字消息传递协议。当客户加入时,他发出这个:

 "%|clientId|need"

并且职位更新如下:

 "$|clientId|xPosition|yPosition"

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

编辑:错误可能在上面的客户端代码中,我认为这是我将Avatars存储在数组中的方式。

这是我的代码:

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;
}

2 个答案:

答案 0 :(得分:1)

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

解决代码后遇到了一些问题。首先是你使用if(str.search)... $和%可以被解析为正则表达式。此外,由于你的字符索引为0,如果这些字符可能不成立。最后你使用的是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);
    }
}

答案 1 :(得分:0)

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