最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • jsliang 求职系列 - 28 - WebSocket

    正文概述 掘金(jsliang)   2020-11-29   423

    一 目录

    不折腾的前端,和咸鱼有什么区别

    目录
    一 目录二 前言三 WebSocket 和 HTTP 3.1 (短)轮询(Polling) 3.2 长轮询 3.3 WebSocket 3.4 两者比对四 Socket.io 4.1 服务端代码 4.2 客户端代码 4.3 小结五 参考文献

    二 前言

    WebSocketHTML5 新增的一种全双工通信协议,客户端和服务器基于 TCP 握手连接成功后,两者之间就可以建立持久性的连接,实现双向数据传输。

    三 WebSocket 和 HTTP

    我们知道 HTTP 协议是一种单向的网络协议,在建立连接后,它允许客户端向服务器发送请求资源后,服务器才会返回相应的数据,而服务器不能主动推送数据给客户端。

    当时为什么这样设计呢?假设一些不良广告商主动将一些信息强行推送给客户端,这不得不说是一个灾难。

    所以现在我们要做股票的实时行情,或者获取火车票的剩余票数等,就需要客户端和服务器之间反复地进行 HTTP 通讯,客户端不断地发送 GET 请求,去获取当前的实时数据。

    下面介绍几种常见的方式。

    3.1 (短)轮询(Polling)

    短轮询模式下,客户端每隔一段时间向服务器发送 HTTP 请求。

    服务器收到请求后,将最新的数据发回给客户端。

    这种情况下的弊端是非常明显的:某个时间段服务器没有更新内容,但是客户端每隔一段时间发送请求来询问,而这段时间内的请求是无效的。

    这就导致了网络带宽的浪费。

    3.2 长轮询

    长轮询模式下,客户端向服务器发出请求,服务器并不一定会立即回应客户端,而是查看数据是否有更新。

    如果数据更新了的话,那就立即发送数据给客户端;如果没有更新,那就保持这个请求,等待有新的数据到来,才将数据返回给客户端。

    如果服务器长时间没有更新,那么一段时间后,请求变会超时,客户端收到消息后,会立即发送一个新的请求给服务器。

    当然这种方式也有弊端:当服务器向客户端发送数据后,必须等待下一次请求才能将新的数据发出,这样客户端接收新数据就有一个最短时间间隔。

    如果服务器更新频率较快,那么就会出现问题。

    3.3 WebSocket

    基于前面的情况,为了彻底解决服务器主动向客户端发送数据的问题。

    W3CHTML5 中提供了一种让客户端与服务器之间进行全双工通讯的网络技术 WebSocket

    WebSocket 基于 TCP 协议,是一种全新的、独立的协议,与 HTTP 协议兼容却不会融入 HTTP 协议,仅仅作为 HTML5 的一部分。

    3.4 两者比对

    基于上面,小伙伴们大概了解了 WebSocket 的缘由了,这里再总结对比一下 HTTPWebSocket

    • 相同点
    1. 都需要建立 TCP 连接
    2. 都属于七层协议中的应用层协议
    • 不同点
    1. HTTP 是单向数据流,客户端向服务器发送请求,服务器响应并返回数据;WebSocket 连接后可以实现客户端和服务器双向数据传递,除非某一端断开连接。
    2. HTTPurl 使用 http// 或者 https// 开头,而 WebSocketurl 使用 ws// 开头

    四 Socket.io

    我们先来看 WebSocket 的一个使用方式:

    const ws = new WebSocket("ws//:xxx.xx", [protocol])
    
    ws.onopen = () => {
      ws.send('hello')
      console.log('send')
    }
    
    ws.onmessage = (ev) =>{
      console.log(ev.data)
      ws.close()
    }
    
    ws.onclose = (ev) =>{
      console.log('close')
    }
    
    ws.onerror = (ev) =>{
      console.log('error')
    }
    

    WebSocket 实例化后,前端可以通过上面介绍的方法进行对应的操作,看起来还是蛮简单的。

    但是,如果想完全搭建一个 WebSocket 服务端比较麻烦,又浪费时间。

    所以:Socket.io 基于 WebSocket,加上轮询机制以及其他的实时通讯方面的内容,实现的一个库,它在服务端实现了实时机制的响应代码。

    也就是说,WebSocket 仅仅是 Socket.io 实现通讯的一个子集。

    因此,WebSocket 客户端连接不上 Socket.io 服务端,Socket.io 客户端也连不上 WebSocket 服务端。

    下面我们讲解下如何实现一个简单的聊天。

    4.1 服务端代码

    {
      "devDependencies": {
        "express": "^4.15.2",
        "socket.io": "^2.3.0"
      }
    }
    
    
    let express = require('express');
    let app = express();
    let server = require('http').createServer(app);
    let io = require('socket.io')(server);
    let path = require('path');
    
    app.use('/', (req, res, next) => {
      res.status(200).sendFile(path.resolve(__dirname, 'index.html'));
    });
    
    // 开启 socket.io
    io.on('connection', (client) => {
    
      // 如果有新客户端进来,显示 ID
      console.log(`客户端 ID:${client.id}`);
    
      // 监听客户端的输入信息
      client.on('channel', (data) => {
        console.log(`客户端 ${client.id} 发送信息 ${data}`);
        io.emit('broadcast', data);
      });
    
      // 判断客户端是否关闭
      client.on('disconnect', () => {
        console.log(`客户端关闭:${client.id}`);
      });
    });
    
    server.listen(3000, () => {
      console.log('服务监听 3000 端口');
    });
    

    如上,我们直接通过 npm i 安装依赖包后,直接通过 node index.js 可以开启服务。

    当然,如果小伙伴们想手动装包,执行下面命令即可:

    npm i express socket.io express -D
    

    4.2 客户端代码

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Socket.io</title>
      <script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.slim.js"></script>
    </head>
    
    <body>
    
      <input type="text" id="input">
      <button id="btn">send</button>
      <div id="content-wrap"></div>
    
      <script>
        window.onload = function () {
          let inputValue = null;
    
          // 连接 socket.io
          let socket = io('http://localhost:3000');
          // 将创建的信息以添加 p 标签的形式展示成列表
          socket.on('broadcast', data => {
            let content = document.createElement('p');
            content.innerHTML = data;
            document.querySelector('#content-wrap').appendChild(content);
          })
    
          // 设置输入框的内容
          let inputChangeHandle = (ev) => {
            inputValue = ev.target.value;
          }
          // 获取输入框并监听输入
          let inputDom = document.querySelector("#input");
          inputDom.addEventListener('input', inputChangeHandle, false);
    
          // 当用户点击发送信息的时候,进行数据交互
          let sendHandle = () => {
            socket.emit('channel', inputValue);
          }
          let btnDom = document.querySelector("#btn");
          btnDom.addEventListener('click', sendHandle, false);
    
          // 打页面卸载的时候,通知服务器关闭
          window.onunload = () => {
            btnDom.removeEventListener('click', sendHandle, false);
            inputDom.removeEventListener('input', inputChangeHandle, false);
          }
        };
      </script>
    </body>
    
    </html>
    

    4.3 小结

    Socket.io 不仅支持 WebSocket,还支持许多种轮询机制以及其他实时通信方式,并封装了通用的接口。

    这些方式包含 Adobe Flash SocketAjax 长轮询、Ajax multipart streaming、持久 IframeJSONP 轮询等。

    换句话说,当 Socket.io 检测到当前环境不支持 WebSocket 时,能够自动地选择最佳的方式来实现网络的实时通信。

    这样,我们就对 WebSocket 有一定的了解,面试的时候就不慌了。

    五 参考文献

    • websocket 与Socket.IO介绍【阅读建议:10min】
    • WebSocket 与 Socket.IO【阅读建议:10min】
    • Websocket和Socket.io的区别及应用【阅读建议:20min】


    起源地下载网 » jsliang 求职系列 - 28 - WebSocket

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元