as3與node.js的socket通信

這裏使用了一個單例的SocketManager類:

1: conn = new Socket();

       2:             

       3: conn.addEventListener(Event.CLOSE, onSocketCloseHandler);

       4: conn.addEventListener(Event.CONNECT, onSocketConnectHandler);

       5: conn.addEventListener(IOErrorEvent.IO_ERROR, onSocketIOErrorHandler);

       6: conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSocketSecurityHandler);

       7: conn.addEventListener(ProgressEvent.SOCKET_DATA, onSocketDataHandler);

SocketManager最多在連接失敗時,進行5次重連。建立socket連接代碼:

1: public function connSocket(url:String, port:Number, _endian:String=""):void

       2: {

       3:     if (conn == null)

       4:     {

       5:         initSocket();

       6:     }

       7:     

       8:     if (_endian == '')

       9:     {

      10:         _endian = Endian.BIG_ENDIAN;

      11:     }

      12:     

      13:     CURR_RECONN_NUM = 0;

      14:     

      15:     conn.endian = _endian;

      16:     

      17:     socket_url = url;

      18:     socket_port = port;

      19:     

      20:     conn.connect(socket_url, socket_port);

      21: }

如果需要發送socket數據,直接調用send方法:

1: /**

       2:  * 發送數據

       3:  */ 

       4: private function send(bytes:IMeteoricByteArray):Boolean

       5: {

       6:     if (checkConnIsSuc() == false)

       7:     {

       8:         return false;

       9:     }

      10:     

      11:     var bytes_len:uint = bytes.size();

      12:     

      13:     var byteArr:ByteArray = new ByteArray();

      14:     

      15:     byteArr.writeInt(bytes_len + headLen);

      16:     byteArr.writeBytes(bytes.getByte());

      17:     

      18:     conn.writeBytes(byteArr);

      19:     conn.flush();

      20:     

      21:     bytes.dispose();

      22:     

      23:     return true;

      24: }

格式:數據包頭部長度(int-帶符號的32位整數)|消息標識(short-16位整數)|消息返回標識(short-16位整數)|…

bytes.writeInt();

bytes.writeShort();

bytes.writeShort();

bytes…

根據不同的消息標識(唯一),後臺獲取標識後調用不同的解析方法,解析客戶端發送的數據

前臺as3建立socket,發送數據、解析數據,網上很多例子,這裏不重點說了。這裏重點介紹node.js如何解析消息(不使用任何第三方庫):

1: var net  = require('net');

       2: var clients = [];

       3:  

       4: var HOST = '127.0.0.1';

       5: var PORT = 7000;

       6:  

       7: net.createServer(function(socket) {    

       8:  

       9:     console.log('Connected: ' + socket.remoteAddress +':'+ socket.remotePort);

      10:  

      11:     clients.push(socket);

      12:  

      13:     socket.on('data', function(data) {

      14:         console.log('receive data:' + socket.remoteAddress +':'+ socket.remotePort);

      15:  

      16:         var isBuffer = Buffer.isBuffer(data);

      17:  

      18:         if (isBuffer) {

      19:             var offset = data['readInt32BE'](0);

      20:             var headCode = data['readInt16BE'](offset);

      21:             offset += 2;

      22:             var headBackCode = data['readInt16BE'](offset);

      23:             offset += 2;         

      24:             

      25:             

      26:             var len = data['readInt16BE'](offset);

      27:             offset += 2;

      28:             

      29:             var msg = data.toString('utf8', offset, offset + len)

      30:  

      31:             console.log(headCode + '-' + headBackCode + '-' + msg);

      32:  

      33:             broadcast(msg, socket);

      34:         } else {

      35:             console.log('Message is not Buffer!');

      36:         }

      37:         

      38:     });

      39:  

      40:     socket.on('end', function() {

      41:         console.log('Close Connected: ' + socket);        

      42:         clients.splice(clients.indexOf(socket));

      43:     });

      44:  

      45:     function broadcast(message, sender) {

      46:         clients.forEach(function(client) {

      47:             //if (client === sender) {

      48:                 client.write(message);

      49:             // }

      50:         });

      51:     }

      52:  

      53: }).listen(PORT, HOST);

      54:  

      55:  

      56: console.log('服務已啓動');

如果一切正常,前臺發送數據時,控制檯上能看到解析的數據:

1000是頭標識,10爲消息返回標識,abcdefg爲發送的字符串。

1: var data:MeteoricSocketSendDataProxy = SocketManager.getInstance().getSocketSendDataProxy(1000, 10) as MeteoricSocketSendDataProxy;

       2: data.addStringData(msg);

       3:  

       4: SocketManager.getInstance().sendDataProxy(data);

上面的解析過程可能比較繁瑣,你可以使用Node.js的ByteBuffer (nodejs的ByteBuffer,和C++通信的利器!)

作者:play175

https://npmjs.org/package/ByteBuffer

使用方法也比較簡單:

//使用ByteBuffer進行解包操作
var buf = new ByteBuffer(data);
var arr = buf.int32()                    
        .short()
        .short()
        .string()            
        .unpack();

console.log(arr);

broadcast(arr[3], socket);


/*************************************************/
//原方法
var offset = data['readInt32BE'](0);
var headCode = data['readInt16BE'](offset);
offset += 2;
var headBackCode = data['readInt16BE'](offset);
offset += 2;         


var len = data['readInt16BE'](offset);
offset += 2;

var msg = data.toString('utf8', offset, offset + len)

console.log(headCode + '-' + headBackCode + '-' + msg);

broadcast(msg, socket);

有興趣的可以下載全部源碼(Flex-SDK4.5 + node.js),點此立即下載>>

參考資料:

AS3 Socket類

Node.js ByteBuffer

Node.js Buffer

http://nodejs.org/api/buffer.html

JavaScript解析二進制數據>>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章