WebSocket


WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,比如说,服务器可以在任意时刻发送消息给浏览器。WebSocket并不是全新的协议,而是利用了HTTP协议来建立连接。在TitanOne框架中用到了WebSocket来通讯,通过websocket来接收服务器推送过来的数据。

为什么要用WebSocket?

为什么传统的HTTP协议不能做到WebSocket实现的功能?这是因为HTTP协议是一个请求-响应协议,请求必须先由浏览器发给服务器,服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的。

HTTP协议其实也能实现啊,比如用轮询或者Comet。轮询是指浏览器通过JavaScript启动一个定时器,然后以固定的间隔给服务器发请求,询问服务器有没有新消息。这个机制的缺点一是实时性不够,二是频繁的请求会给服务器带来极大的压力。

Comet本质上也是轮询,但是在没有消息的情况下,服务器先拖一段时间,等到有消息了再回复。这个机制暂时地解决了实时性问题,但是它带来了新的问题:以多线程模式运行的服务器会让大部分线程大部分时间都处于挂起状态,极大地浪费服务器资源。另外,一个HTTP连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,而网关是我们不可控的,这就要求Comet连接必须定期发一些ping数据表示连接“正常工作”。

以上两种机制都治标不治本,所以,HTML5推出了WebSocket标准,让浏览器和服务器之间可以建立无限制的全双工通信,任何一方都可以主动发消息给对方。

WebSocket协议

WebSocket是为解决客户端与服务端实时通信而产生的技术,websocket协议本质上是一个基于tcp的协议,首先通过HTTP/HTTPS协议发起一条特殊的http请求进行握手,然后创建一个用于交换数据的TCP连接,此后服务端与客户端通过此TCP连接进行实时通信。

node上有多种websocket模块可以选择,TitanOne的websocket组件是基于模块ws ,因为它不需要在客户端挂额外的js文件。不像socket.io 模块,ws 是一个单纯的websocket模块,不提供向上兼容(也就是fallback),使用最新浏览器的原生Websocket API即可通信。

erayt-elws组件

由于ws 模块不支持多服务器地址和断线重连机制,所以我们开发的erayt-elws在原来ws基础上增加了这两个功能,也就是说erayt-elws除了支持websocket通讯以外,还支持配置多个服务端地址,并且当服务端某个机器宕机或者网络断线的情况下,erayt-elws组件能够在一定时间间隔内多次重连该机器,如果超时则更换服务端地址进行连接,直到连接成功或者手动关闭erayt-elws组件为止。

安装

  1. npm i erayt-elws -S

使用

  • 调用模块
  1. const RWS = require('erayt-elws');
  • 配置连接
    配置多个服务端的地址,服务端地址之间用;进行分割,最后面两个参数分别为每次重连的定时器间隔(单位为ms),以及每个服务端地址重连的最大次数。
  1. const client = new RWS('ws://echo.websocket.org;ws://localhost:8080', null, 25000,5);
  2. //两个服务端地址,25秒重连一次,每个地址最多重连5次
  • 处理事件
  1. client.onopen = function () {
  2. //此链接开启后做些什么
  3. };
  4. client.onmessage = function (event) {
  5. //对接收到的消息做些什么
  6. };
  7. client.onerror = function ()(err){
  8. //处理错误
  9. };
  10. client.onclose = function (){
  11. //连接关闭时做些什么
  12. };
  • 开始连接
  1. client.connect();
  • 关闭连接
  1. client.forceClose(1000);//1000代表关闭的代码,可以不写,默认值就是1000
  • 发送数据
  1. client.send('something');

其他的一些发送PING、PONG或者暂停继续的操作参考官方文档:Usage Example