pomelo源码解析之模块解析(五)

慕容星晖
2023-12-01

  • pomelo/lib/connectors

    4个模块都是服务器,都是继承自EventEmitter,只是支持的通信协议有差别

  • 1. sioconnector

    通信协议:基于socket.io的websocket
    消息流:json明文
    内部加密: 无
    外部加密:encode并没有实现
    支持参数:心跳,心跳超时,关闭超时等
    返回的socket: siosocket

    代码结构:
    导出的是一个函数Connector,也就是说是用该模块需要这样:
    var sio = require(‘sioconnector’)(port, host, opts);或者使用new创建
    返回的sio有如下接口:
    start();
    stop();
    encode(reqId, route, msg);
    decode(msg);

    在start中启动后,会调用socket.io创建一个http服务器,设置一些属性
    当接收到’connection’消息后,会创建一个SioSocket对象把真正的socket封装一层
    这里也会发送一次’connection’供上层调用:

var sio = require('sioconnector')(port, host, opts);
sio.on('connection', function(SioSocket){
	// do something
});

再看一下SioSocket的实现(继承自EventEmitter),发现处理了disconnect,error,message消息,原封不动返回给上层调用
SioSocket提供接口:
send(msg); // json字串或者json对象
disconnect();
sendBatch(); // json字串数组或者json对象数组

所以对于上边的来说,可以这样使用

var sio = require('sioconnector')(port, host, opts);
sio.on('connection', function(SioSocket){
// SioSocket.send(msg);
// SioSocket.disconnect();
// SioSocket.sendBatch(msgArray);
// SioSocket.on('disconnect', function(){});
// SioSocket.on('error', function(){});
// SioSocket.on('message', function(){});
});
//sio.start();
//sio.stop();
//sio.encode(reqId, route, msg);
//sio.decode(msg);
  • 2. hybridconnector

    通信协议:基于net(TCP)或者tls(支持ssl)
    消息流:ws标准编码 TCP:字节流
    内部加密: ws自带,tcp字节流
    外部加密:lib/connectors/common/coder.js 最终加解密在pomelo-protocol/lib/protocol.message.decode
    支持参数:ssl 连接超时 是否握手 是否心跳等 使用路由字典 使用protobuf 监听特定ip
    返回的socket: hybridsocket

    代码结构:
    hybridconnector创建server并监听端口,并把服务器传入Switcher
    -> Switcher监听’connection’ -> Switcher.newSocket() 监控data消息(如果是http通讯就是websocket否则是TCP)
    这里只处理一次用于触发进一步的封装,后续由封装类处理
    -> wsprocessor或者tcpprocessor的add函数
    -> 返回’connection’消息
    在这里对原始socket进行了封装并在封装中处理消息
    websocket: ws+http
    TCP:lib/connectors/hybrid/tcpsocket
    -> 把封装好的socket返回给上层调用hybridconnector.gensocket 进一步封装
    -> hybridsocket注册message消息[接下1]
    -> websocket处理:如果原始socket.ondata存在则调用,否则发送原始socket的’data’消息
    因为ws+http的接管,最后会向上层返回message消息
    -> tcpsocket处理:接收消息流解析并返回message消息
    [接上1]
    -> hybridsocket.js中handler处理具体消息,发现有4种消息类型[握手,握手返回,心跳,数据]
    -> 返回给上层对应的消息,‘handshake’,‘heartbeat’,‘message’
    -> gensocket最后给上层发送connection消息,带入hybridSocket // 这里接管的’message’就是具体的通信消息

    最终的调用方式基本同sioconnector

  • 3. udpconnector

    通信协议:基于dgram
    消息流:dgram字节流
    内部加密:pomelo/lib/connectors/mqtt/generate
    外部加密:lib/connectors/common/coder.js 最终加解密在pomelo-protocol/lib/protocol.package.decode
    支持参数:心跳 握手 udp类型
    返回的socket: udpsocket

    流程比较简单就不再分析了

  • 4. mqttconnector

    通信协议:基于mqtt
    消息流:mqtt编码流
    内部加密: pomelo/lib/connectors/mqtt/generate
    外部加密:无
    支持参数:心跳 握手 udp类型
    返回的socket: mqttsocket

    流程比较简单就不再分析了

  • 总结

    通常做socket封装的话,需要把消息传回最外层,那么最里层一般会保存有外层指针(或对象),然后层层调用出来。
    在pomelo中使用了EventEmitter,那么只需要内层给自身对象发射消息,外层使用该对象接手即可。

    以上4个服务器socket的封装就是这样子,封闭内部细节,对外封装出统一接口。

 类似资料: