• 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解析二进制数据>>

  • 相关阅读:
    VSCode前端 插件
    restframework 分页组件、响应器
    restframework 解析器、渲染器、url控制组件
    __getattr__
    apply和call的用法
    继承
    原型的指向改变
    局部变量变全局变量
    构造函数和实例对象和原型对象之间的关系
    _proto_和prototype
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/2819563.html
Copyright © 2020-2023  润新知