浅谈WebSocket

简介: WebSocket是一种基于http的通信协议,服务端可以主动推送信息给客户端,客户端也可以向服务端发送请求,WebSocket允许服务端与客户端进行全双工通信。

WebSocket是一种基于http的通信协议,服务端可以主动推送信息给客户端,客户端也可以向服务端发送请求,WebSocket允许服务端与客户端进行全双工通信。


特点


  • 基于tcp协议之上,服务端实现比较容易


  • 默认端口是80(ws)或者443(wss),握手阶段采用的http协议


  • 数据格式比较轻量,性能开销小,通信高效


  • 可以发送文本或者二进制数据


  • 没有同源限制,客户端可以向任意服务器发送信息


  • 协议标识符是ws,如果加密,那么是wss

e36ece7ab5b25eb8249bacf237b06616.png


实现客户端与服务端通信


新建一个html文件客户端代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>websocket</title>
</head>
<body>
  <h3>hello websocket</h3>
  <input type="number" id="textContent" />
  <button id="handleSend">发送</button>
  <button id="auto-send">开启服务端向客户端发消息模式</button>
  <hr />
  <div id="app"></div>
</body>
</html>

html中引入下面一段js

// index.js
    const sendDom = document.getElementById('send');
    const appDom = document.getElementById('app');
    const autoDom = document.getElementById('auto-send');
    const inputContent = document.getElementById('textContent');
    const socketPath = 'ws://192.168.31.40:3000';
    let timer = null;
    let num = 0;
    const result = [];
    // 建立连接
    const ws = new WebSocket(socketPath);
    const sendMyNum = (isSetInterval = false, to = 'client', val) => {
      const setNum = () => {
        num = val || Math.ceil(Math.random() * 10);
        ws.send(
          JSON.stringify({
            clientText: `client:hello,我是 ${num}号`,
            num,
            to
          })
        );
      };
      if (isSetInterval) {
        timer = setInterval(() => {
          setNum();
        }, 1000);
      } else {
        setNum();
      }
    };
    const renderHtml = (data) => {
      const { serverText, clientText } = JSON.parse(data);
      appDom.innerHTML = '';
      result.push({
        serverText,
        clientText
      });
      console.log(result);
      if (result.length > 0) {
        let str = '';
        result.forEach((v) => {
          str += `<ul>
              <li>${v.clientText}</li>
              <li>${v.serverText}</li>
            </ul>`;
        });
        appDom.innerHTML = str;
      }
    };
    // 发送数据
    ws.onopen = function () {
      console.log('websocket connection start');
      sendMyNum(false);
    };
    // 接收服务端发送的消息
    ws.onmessage = function (evt) {
      console.log(`receive:${evt.data}`);
      if (evt.data) {
        renderHtml(evt.data);
        // 接收数据后关闭定时器
        clearInterval(timer);
        // sendMyNum(true)
      }
    };
    // 关闭连接
    ws.onclose = function () {
      console.log('关闭了');
    };
    // 手动向客户端发送消息
    handleSend.onclick = function () {
      const val = inputContent.value;
      if (val === '') {
        alert('请输入你的编号');
        return;
      }
      sendMyNum(false, 'client', val);
    };
    // 自动开启向客户端发送消息
    autoDom.onclick = function () {
      sendMyNum(true, 'server');
    };

新建一个server目录,创建服务端代码,主要依赖`nodejs-websocket`[1]这个库是服务端websocket代码。

var ws = require("nodejs-websocket");
var http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = 8080;
var server = http.createServer(function (request, response) {
  response.statusCode = 200;
  response.setHeader('Content-Type', 'text/html');
  fs.readFile(path.resolve(__dirname, '../', 'index.html'), (err, data) => {
    if (err !== null) {
      response.end('404');
      return;
    }
    response.end(data);
  })
});
server.listen(PORT, function (evt) {
  console.log((new Date()) + ' Server is listening on port 8080');
});
// websocket
const tcp = ws.createServer(function (connection) {
  console.log("New connection")
  connection.on("text", function (data) {
    const { clientText, num, to } = JSON.parse(data);
    if (to === 'server') {
      connection.sendText(JSON.stringify({
        serverText: `server:${num}号,恭喜你,你太幸运了,你已经被清华录取了`,
        clientText: `${num}号`
      }));
    } else {
      if (num > 6) {
        connection.sendText(JSON.stringify({
          clientText,
          serverText: `server:${num}号,你非常优秀, ${num}号,你已经成功被录取了北京大学`,
        }))
      } else {
        connection.sendText(JSON.stringify({
          serverText: `server: ${num}号,非常遗憾,${num}号,你落榜了,再接再厉`,
          clientText,
        }));
      };
    }
  });
  connection.sendText(JSON.stringify({
    serverText: `server:hello,我们已经建立连接了`,
    clientText: `client:你好`
  }))
  connection.on("close", function (code, reason) {
    console.log("Connection closed");
    console.log(code, reason);
  });
}).listen(3000);
tcp.on('error', (err) => {
  console.log(err);
})

我们可以执行命令node server.js,打开浏览器http://localhost:8080/

66cb8117235815fa8b45e1ae0d11524a.png

打开network,ws下面可以看到有客户端向服务端发送的消息,也有服务端向客户端发送的两条信息。


我们看到请求头的一些信息

4f7106efb8c130cde971302b0c00287d.png

我们可以看到请求头里


General


Request URL: ws://192.168.31.40:3000/
Request Method: GET
Status Code: 101 Switching Protocols


Request Headers


Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: Upgrade
Host: 192.168.31.40:3000
Origin: http://localhost:8080
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: Mk8Au85XqQTn+vuDsfr/kw==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36

当输入数字,向服务端发送消息时,服务端会返回对应信息。通常来讲,服务端会不定时的向客户端推送信息,客户端拿到推送信息进行一系列的页面状态展示等。


通过以上的例子,我们基础的了解到websocket的使用


总结


WebSocket其实需要客户端对WebSocket处理主要是这三个步骤


  • 建立连接、断开连接


  • 发送数据,接收数据


  • 处理错误


  • 本文 示例代码[2]
相关文章
|
21天前
websocket 的使用
websocket 的使用
|
前端开发 网络协议 API
什么是WebSocket?
WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。
1434 0
什么是WebSocket?
|
4天前
|
XML JSON 前端开发
WebSocket是什么
【4月更文挑战第27天】WebSocket,即Web浏览器与Web服务器之间全双工通信标准。
|
25天前
websocket
websocket
14 0
|
3月前
|
移动开发 网络协议 安全
Websocket
Websocket
|
3月前
|
移动开发 网络协议 前端开发
WebSocket一
WebSocket一
|
3月前
|
移动开发 网络协议 Java
WebSocket二
WebSocket二
|
6月前
|
监控 前端开发 安全
你使用过websocket吗?
你使用过websocket吗?
35 0
|
9月前
|
网络协议 定位技术 PHP
【说说你对webSocket的理解?】
【说说你对webSocket的理解?】
|
10月前
|
监控 数据可视化 应用服务中间件
为什么要用webSocket?
为什么要用webSocket?
77 0