首页 > 资讯 > > 内容页

学习websocket,原来这么简单

发表于: 2023-06-26 11:38:32 来源:博客园


(资料图片)

简单介绍 websocket
WebSocket是一种在TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准。然后WebSocket API也被W3C定为标准。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手。两者之间就直接可以创建持久性的连接,并进行双向数据传输。
我们为什么要使用 websocket
我们都知道 HTTP 协议有一个缺陷。那就是通信只能由客户端发起。服务端没法主动发起。有些场景我们需要让客户端实时知道消息。虽然可以使用轮询来解决这个问题。但是非常浪费资源,因为要不停连接,断开后又继续连接。这个时候我们就需要使用 websocket
websocket 应用场景
1.弹幕媒体聊天 [客服推送]2.协同编辑 [wps]3.基于位置的应用 [外卖]4.体育实况更新5.股票帮金报价实时更新
websocket 和HTTP请求的不同点:
1.WebSocket是双向通信协议,HTTP是单向的WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息。而HTTP是单向的2.连接方式不同WebSocket是需要浏览器和服务器握手进行建立连接的。http是浏览器发起向服务器的连接,服务器预先并不知道这个连接。3.协议开头不同websocket:websocket的协议是以 ws/wss 开头。http 对应的是 http/https4.连接长度不同websocket是持久连接。http 是短连接。
简单实现一下 WebSocketnode创建WebSocket
我们需要先下载 npm install wsws是一个简单易用、快速且经过全面测试的WebSocket客户端和服务器实现。我们就直接使用就好了
const express = require("express")const app = express()const port = 3000// 托管静态资源-express.static()app.use(express.static("public"))app.get("/", (req, res) => res.send("Hello World!"))app.listen(port, () => console.log(`Example app listening on port ${port}!`))// 引入 ws,并且解构使用我们需要的 WebSocketServer        const { WebSocketServer } = require("ws");// 创建WebSocketServer的实例wss,并指定端口号const wss = new WebSocketServer({ port: 8080 });// 通过实例wss进行监听wss.on("connection", function connection(ws) {  ws.on("error", console.error);  // 接收客户端发送过来的消息  ws.on("message", function message(data) {    console.log("客户端发送过来的消息", data);  });  ws.send("服务端发送的消息");});
客户端 WebSocket 的创建
我们需要创建 WebSocket 的实例同时指定端口号。然后通过 onopen  onmessage onerror 来判断ws的状态事件下面我们就来简单写一下
    

欢迎 学习WebSocket

<script>// 创建 WebSocket并指定一个地址let ws = new WebSocket("ws://localhost:8080")// 是否链接成功ws.onopen = (() => { console.log("链接成功")})// 监听服务端发送过来的消息ws.onmessage = ((messObj) => { console.log("发送过来的消息", messObj)})// 连接失败ws.onerror = (() => { console.log("连接失败")})</script>
客户端发送消息给服务端
我们需要写一个简单的html界面,获取到 文本域中的内容。然后通过 ws.send(textareaValue) 给服务端发送消息。服务端在 ws.on("message", function message(data) {  console.log(data)}) 这个方法中接收客户端的消息data就是客户端发送过来的消息如果是二进制数据,我们可以使用 data.toString()进行转换
    

欢迎 学习WebSocket

// 创建 WebSocket并指定一个地址let ws = new WebSocket("ws://localhost:8080")let textarea=document.getElementById("textarea")function sendHandler(){ const textareaValue = textarea.value; // 通过ws.send给客户端发送消息 ws.send(textareaValue)}
WebSocket 实现广播
我们要做一个广播。就有点类似在QQ群中发送一条消息,在这个群中的其他用户可以接收到这条消息。WebSocket 连接成功后,wss.clients来获取当前服务端连接了多少个客户端。wss.clients是一个Set类型的。我们通过 forEach 来进行遍历。我们通过 client.readyState 的状态是否是 WebSocket.OPEN然后调用 client.send(data, { binary:false  })就数据发送出去
// 引入 ws,并且解构使用我们需要的 WebSocketServer        const { WebSocketServer, WebSocket } = require("ws");// import { WebSocketServer } from "ws";// 创建WebSocketServer的实例wss,并指定端口号const wss = new WebSocketServer({ port: 8080 });// 通过实例wss进行监听wss.on("connection", function connection(ws) {  ws.on("error", console.error);  // 客户端  ws.on("message", function message(data) {    console.log("received: %s", data);    // 服务器广播    // 广播到所有连接的WebSocket客户端,包括其自身。    console.log("连接了多少个",wss.clients.size)    wss.clients.forEach(function each(client) {      // 判断当前连接服务端的所有客户端的ws。      if (client.readyState === WebSocket.OPEN) {        // binary表示数据是否是二进制。binary:false表示不是二进制        client.send(data, { binary:false  });      }    });  });  ws.send("服务端发送的消息");});
发现自己也被广播了
假设不同的浏览器代码一个用户。通过上面的图片,我们发现谷歌浏览器发送一条消息。虽然火狐浏览器接收到了。但是谷歌发送的消息自己也接收到了。这样明显是不正确的。因此。我们处理一下。自己发送的消息不需要广播自己的。我们使用 client!==ws 来进行判断
// 引入 ws,并且解构使用我们需要的 WebSocketServer        const { WebSocketServer, WebSocket } = require("ws");// import { WebSocketServer } from "ws";// 创建WebSocketServer的实例wss,并指定端口号const wss = new WebSocketServer({ port: 8080 });// 通过实例wss进行监听wss.on("connection", function connection(ws) {  ws.on("error", console.error);  // 客户端  ws.on("message", function message(data) {    console.log("received: %s", data);    // 服务器广播    // 广播到所有连接的WebSocket客户端,包括其自身。    console.log("连接了多少个",wss.clients.size)    wss.clients.forEach(function each(client) {      // 判断当前连接服务端的所有客户端的ws用户。      // client!==ws 表示不是当前发送的用户[不要自己广播自己]      if (client!==ws && client.readyState === WebSocket.OPEN) {        // binary表示数据是否是二进制。binary:false表示不是二进制        client.send(data, { binary:false  });      }    });  });  // 第一次连接成功后发送的消息。  ws.send("");});
实现关闭页面关闭 WebSocket
当我们离开连接 WebSocket的页面离开后,我们应该关闭当前连接。可是现在我们点击去user页面的时候,并没有关闭连接。这显然是不太好的。所以我们需要优化一下。当用户离开,我们需要关闭连接
// 关闭当前窗口,按下 F5 或点击以下链接触发 onbeforeunload 事件document.body.onbeforeunload = function () {  ws.close()  return "close"}//离开当前页面会触发window.onunload = function (e) {  var e = window.event || e;  console.log("===>",e)  // 离开页面,关闭WebSocket  ws.close()}
携带token
我们在连接 WebSocket 的时候,没有鉴权,也就是说无法判断当前这个用户的信息。这样是不安全的。因此我们在连接 WebSocket 需要携带token.通过这样的形式携带  ws://localhost:8080?token=" + "tokne_zahngsan"
// 创建 WebSocket并指定一个地址,并且携带一个tokenlet ws = new WebSocket("ws://localhost:8080?token=" + "tokne_zahngsan")//省略其他代码
wss.on("connection", function connection(ws,req) {  // 获取前端携带的token  console.log("req", req.url.slice(8))})
标签:

Copyright ©  2015-2022 南非公司网版权所有  备案号:沪ICP备2022005074号-13   联系邮箱:58 55 97 3@qq.com