Web Socket初认识

355 阅读3分钟

为什么需要Web Socket

  假设我们使用过http,应该清楚它是客户端和服务端『快问快答』的过程。比如使我用『http』进入咖啡店可能是这样的情景。

我:你好,最近有什么新品吗?

店员:没有~

我:那有什么优惠活动吗?

店员:美式第二杯半价哦~

我:那我要两杯美式吧

店员:好的,稍等~

  接下来有趣的事情发生了。

我:你好,我的咖啡好了吗?

店员:还没有~

a few moments later......

我:咖啡好了吗?

店员:好了,您拿好~

  在反复地询问中,店员应该很想抱怨顾客的啰嗦吧(但是http的服务端不能主动抱怨);顾客应该在过程中不耐烦了吧(客户端还有其他的事情要忙)。

  生活中我们也不是这样做的。我们会基于常识调整『轮询』的间隙,如果对于咖啡的认知是6分钟,我们可能会在4-8分钟加快『轮询』的频率。而且我们也会东张西望,发现晚于自己下单的某人取到餐了,开始询问。可惜的是,客户端之前一般不能张望。

  那么如果用Web Socket会怎样。

我:那我要两杯美式吧

店员:好的,你的单号是A01,稍后叫号取餐~

a few moments later......

店员:A01号顾客取餐~

我:好的

  体验提升了一些,店员在下单到交付过程中可以主动和顾客说话了;顾客在过程中也有一定的自由度,体现在不必反复去询问、只要呆在听得见叫号的地方忙些其他事情也可以。

  如果说http是快问快答,那Web Socket就是和客服打电话。特点如下:

  1. 需由客户端发起,建立连接为http握手过程。
  2. 通信基础为,双方都保持链接。
  3. 过程为全双工,双方都可主动通信。
  4. 通信过程不宜太长,服务端保持链接占用资源(内存记录通信上下文、服务器并发量)。

如何使用Web Socket

  因为是全双工的协议,客户端和服务端的行为大致对称。* 以下服务端为node.js,自行载入ws npm包。 *

浏览器

// 建立连接
const ws = new WebSocket('ws://localhost:8080');
ws.onopen = function (err) {
    // 连接建成
};
ws.onmessage = function (data) {
    // 收到信息
};
ws.onerror = function (err) {
    // 连接报错
};
ws.onclose = function (reason) {
	// 连接断开
}
// 发送消息
ws.send('to server');
// 关闭连接
ws.close();

服务端

const WebSocket = require('ws');
// 监听连接
const websocket = new WebSocket.Server({ port: 8080 });
websocket.on('connection', ws => {
    // 连接建成
    ws.on('message', data => {
        // 收到信息
    });
    ws.on('error', err => {
        // 连接报错
    });
    ws.on('end', ws => {
        // 连接断开
    });
    // 发送消息
    ws.send('to client');
    // 关闭连接
    ws.close();
});

疑问

  ** 异常处理: **一次http请求可以通过状态码判断请求成功与否,但是在Web Socket中send方法的异常是异步抛出的,不知道如何通过js程序捕获?error事件可以监听报错,但是无法为每个信息定位?

switch (ws.readyState) {
    case ws.OPEN :
        ws.send('to server');
        break;
    case ws.CONNECTING :
        console.log('CONNECTING');
        break;
    case ws.CLOSING :
        console.log('CLOSING');
        break;
    case ws.CLOSED :
        console.log('CLOSED');
        break;
}

  这样的预检查可以解决一部分问题,相当于打电话『喂,在听吗』『嗯,我在』。但是后面的通话异常还是不能被说话人得知。就像『不好意思,我没听清』,我们是通过电流声、前后语义连贯性做出的判断,如果是一整段话的缺失,我们也无法察觉。但是,Web Socket不管连贯性的,通信过程的异常处理是如何保证的呢,望大佬指点![抱拳] [抱拳] [抱拳]