NodeBB的实时通讯流程 -- 基于socket.io

       NodeBB是一款响应式设计的论坛程序,是移动时代的论坛解决方案,它是基于Node.js的产品 nodebb on github。移动时代,消息通讯成为必要功能,NodeBB的解决方案是通过socket.io来封装消息,实现消息的实时传输。socket.io提供了一套完整的前后端解决方案,兼容多语言,跨平台,通过polling和WebSocket来切换的方式完美解决各种版本的不同浏览器(全球还有不少IE6的用户)。

       WebSocket一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。轮询技术占用了大量的带宽。而较新都Comet技术,普遍采用的长链接,也会消耗服务器资源。在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

NodeBB的server端socket.io

server端核心socket.io代码路径位于: 根目录 > src > socket.io

启动websocket服务:

/app.js  (require('./src/start').start();) 
     ↓
/src/start.js (里面有3步)
     ↓
/src/webserver.js (初始化 webserver) ①
     ↓
/src/socket.io/index.js (初始化 socket.io)②
     ↓
/src/webserver.js (添加 webserver 监听器) ③

       核心参数的传递在socket对象中,使用redis来实现消息的sub-pub模式。使用 socketio-wildcard 框架来作为事件通配符处理,在各种模块消息传输过程中,不用每个模块都添加相关的filter/middleware处理。

socket.on('*', function (payload) {  
    onMessage(socket, payload);
});

       在onMessage函数中注册每个module中的方法,当有新的方法加入时,不用添加socket.on的监听代码,直接能够让方法约定注册到socket.io事件监听中去。代码为:

var eventName = payload.data[0];  
    var params = payload.data[1];
    var callback = typeof payload.data[payload.data.length - 1] === 'function' ? payload.data[payload.data.length - 1] : function () {
    };

    if (!eventName) {
        return winston.warn('[socket.io] Empty method name');
    }

    var parts = eventName.toString().split('.');
    var namespace = parts[0];
    var methodToCall = parts.reduce(function (prev, cur) {
        if (prev !== null && prev[cur]) {
            return prev[cur];
        }
        return null;
    }, Namespaces);

每次新的模块加入时,不用都添加监听,采用约定的方式来调用。约定为 select.emit(className.functionName, data)

NodeBB的client端socket.io

client端核心的socket.io代码路径位于: 根目录 > public > src > sockets.js

主要处理了几个核心事件:

  • connect
  • reconnecting
  • disconnect
  • reconnect_failed
  • checkSession
  • event:banned
  • event:alert

客户端的监听器较少,所以没有自动注册,采用的手动命名的方式。NodeBB V1.4.6 中:

  • 根目录> public > src > client的目录下面,有22处socket.on监听事件处理。
  • 根目录> public > src > modules 中有6个事件监听!

合计总共有28个socket.io的时间client监听。


不仅仅是NodeBB采用了socket.io来作为实时通讯的框架,知名团队任务管理软件trello也是采用socket.io来做类似的事情。