这里使用了一个单例的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),点此立即下载>>
参考资料: