這裏使用了一個單例的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),點此立即下載>>
參考資料: