2010-11-27 4 views
1

Я работаю над Flash MMO с сервером C#. У меня есть простой протокол обмена сообщениями для сокетов. Когда клиент присоединяется он посылает это:AS3 Socket/Server MMO Communication

"%|clientId|need" 

И позиции обновляются так:

"$|clientId|xPosition|yPosition" 

По какой-то причине это не работает. Я сохраняю все аватары в массиве, класс аватара просто расширяет мувиклип. Это должно добавить всех клиентов в комнату, но она не работает. Есть идеи?

Редактировать: Вероятно, ошибка связана с кодом на стороне клиента, я думаю, что это с тем, как я храню аватары в массиве.

Вот мой код:

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

Я не вижу ваш код пакетирования, то есть где вы гарантируете, что сообщение дошло до его разбора. И сохранение части сообщения, которое не относится к текущему пакету, который будет использоваться в будущем пакете. – CodesInChaos 2010-11-28 18:56:33

+0

И ваши идентификаторы не уникальны – CodesInChaos 2010-11-28 18:57:49

ответ

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

Перед тем, как проверить войти/выйти/положение, убедитесь, что ваша архитектура поддерживает отправку и прием данных, в первую очередь, я имею в виду, послать строку (» некоторые данные ") в интерфейсе и проверьте, действительно ли вы получаете (« некоторые данные ») на внутреннем сервере. Я боюсь, что байт-континент, который вы отправляете на клиенте, отличается от того, что на сервере, и поэтому сервер будет неправильно понимать входящие данные. Если это так, вам нужно преобразовать входящие сообщения в подходящую контенту, прежде чем пытаться их обработать.

+0

Flash принимает сообщения в порядке, у меня есть журнал, который отображает все сообщения. Мой сервер принимает сообщение клиента и отправляет его всем другим клиентам. – alex 2010-11-28 18:01:22