你真的了解websocket吗

一、概述

http1.0余http1.1支持长连接的详解
HTTP作为应用层协议,其实它的生命周期在服务器返回结果时就已经结束了,而所谓的支持长连接,其实是基于’Keep-Alive’请求头所约定,从而向下进行长连接发起的一种机制。该长连接依然是基于TCP的。
因此:
所谓HTTP1.1及以上支持长连接,并不是HTTP1.1可以建立长连接,而是它支持以请求头的方式进行长连接发起(并且要求客户端与服务端都要具备 ‘Keep-Alive: true’ )。
再说websocket之前,我们必须知道的是什么是半双工通信、双工通信、全双工通信。

1、半双工通信

1、同一时刻数据是单向流动的,客户端向服务端请求数据->单向,服务端向客户端返回数据->单向
2、服务器不能主动的推送数据给客户端

2、双工通信

  • 长轮询(长轮询及是在请求的过程中,若是服务器端数据并没有更新,那么则将这个连接挂起,直到服务器推送新的数据,再返回,然后再进入循环周期。)

长轮询 本质上是原始轮询技术的一种更有效的形式。向服务器发送重复请求会浪费资源,因为必须为每个新传入的请求建立连接,必须解析请求的 HTTP 头部,必须执行对新数据的查询,并且必须生成和交付响应(通常不提供新数据)。然后必须关闭连接并清除所有资源。长轮询是一种服务器选择尽可能长的时间保持和客户端连接打开的技术,仅在数据变得可用或达到超时阙值后才提供响应,而不是在给到客户端的新数据可用之前,让每个客户端多次发起重复的请求。

  • 短轮询(短轮询指的是在循环周期内,不断发起请求,每一次请求都立即返回结果,根据新旧数据对比决定是否使用这个结果。)
  • iframe流

3、全双工通信(要知道它属于应用层的协议,它基于TCP传输协议,并复用HTTP的握手通道)(在客户端和服务端上建立了一个长久的连接,两边可以任意发数据)

二、我们好好聊聊websocket

1、写一写前端简单的websocket

// 创建一个index.html文件
// 下面直接写WebSocket

// 只需要new一下就可以创建一个websocket的实例
// 我们要去连接ws协议
// 这里对应的端口就是服务端设置的端口号9999
let ws = new WebSocket('ws://localhost:9999');

// onopen是客户端与服务端建立连接后触发
ws.onopen = function() {
    ws.send('哎呦,不错哦');
};

// onmessage是当服务端给客户端发来消息的时候触发
ws.onmessage = function(res) {
    console.log(res);   // 打印的是MessageEvent对象
    // 真正的消息数据是 res.data
    console.log(res.data);
};

2、写一写node 的websocket
我们在用时要安装ws包

// 创建一个index.html文件
// 下面直接写WebSocket

// 只需要new一下就可以创建一个websocket的实例
// 我们要去连接ws协议
// 这里对应的端口就是服务端设置的端口号9999
let ws = new WebSocket('ws://localhost:9999');

// onopen是客户端与服务端建立连接后触发
ws.onopen = function() {
    ws.send('哎呦,不错哦');
};

// onmessage是当服务端给客户端发来消息的时候触发
ws.onmessage = function(res) {
    console.log(res);   // 打印的是MessageEvent对象
    // 真正的消息数据是 res.data
    console.log(res.data);
};

3、兼容性问题的解决(socket.io)

  1. socket.io的特点

易用性:封装了服务端和客户端,使用简单方便
跨平台:支持跨平台,可以选择在服务端或是客户端开发实时应用
自适应:会根据浏览器来自己决定是使用WebSocket、Ajax长轮询还是Iframe流等方式去选择最优方式,甚至支持IE5.5

  1. 安装(npm i socket.io -S)
  2. 启动服务,手写服务端
// server.js文件
const express = require('express');
const app = express();
// 设置静态文件夹
app.use(express.static(__dirname));
// 通过node的http模块来创建一个server服务
const server = require('http').createServer(app);
// WebSocket是依赖HTTP协议进行握手的
const io = require('socket.io')(server);
// 监听客户端与服务端的连接
io.on('connection', function(socket) {
    // send方法来给客户端发消息
    socket.send('青花瓷');
    // 监听客户端的消息是否接收成功
    socket.on('message', function(msg) {
        console.log(msg);  // 客户端发来的消息
        socket.send('天青色等烟雨,而我在等你' );
    });
});
// 监听3000端口
server.listen(3000);

  1. 前端代码(在服务端运行后,客户端就需要引用一个动态生成的文件路径,路径是固定的直接引用即可(/socket.io/socket.io.js))
// index.html文件
...省略
// 引用socket.io的js文件
<script src="/socket.io/socket.io.js"></script>
<script>
    const socket = io('/');
    // 监听与服务器连接成功的事件
    socket.on('connect', () => {
        console.log('连接成功');
        socket.send('周杰伦');
    });
    // 监听服务端发来的消息
    socket.on('message', msg => {
        // 这个msg就是传过来的真消息了,不用再msg.data取值了
        console.log(`客户端接收到的消息: ${msg}`);  
    });
    // 监听与服务器连接断开事件
    socket.on('disconnect', () => {
        console.log('连接断开成功');
    });
</script>

其实我自己用到的socket还是比较少,就是项目中用到了websocket,然后引申了一下,如果有时间会好好整理一下socket.io,
若有不正确的地方,请联系我改正,谢谢!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章