IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> WebSocket -> 正文阅读

[网络协议]WebSocket

是什么

由于TCP是服务器被动通信,无法主动向客户端发送信息,所以有了websocket
可以双向通信
服务端监听自身端口+客户端连接服务器地址和该端口,达成通信成功!(类似于Java的socket通信)

使用的是Http连接来建立:

(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL(ws://example.com:80/some/path)。

在这里插入图片描述
参考:https://www.ruanyifeng.com/blog/2017/05/websocket.html

如何建立

必须由浏览器发起!因为是一个HTTP请求
请求头:

GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13

注意点:

  • 地址以ws://目标地址:端口开始
  • connection指定连接升级
  • upgrade指定升级成websocket协议
  • 13是websocket协议版本号

返回值:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string

注意:101标识HTTP协议将被替代成websocket协议!标识连接成功!

安全的WebSocket连接机制和HTTPS类似。首先,浏览器用wss://xxx创建WebSocket连接时,会先通过HTTPS创建安全的连接,然后,该HTTPS连接升级为WebSocket连接,底层通信走的仍然是安全的SSL/TLS协议

websocket 常用 api

// 构造函数
WebSocket WebSocket(url)

// 属性
// 用于指定连接关闭后的回调函数
webSocket.onclose
// 用于指定连接失败后的回调函数
webSocket.onerror
// 用于指定当从服务器接受到信息时的回调函数
webSocket.onmessage
// 用于指定连接成功后的回调函数
webSocket.onopen
// 查询当前连接状况:
// CONNECTING:值为0,表示正在连接。
// OPEN:值为1,表示连接成功,可以通信了。
// CLOSING:值为2,表示连接正在关闭。
// CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
webSocket.readyState

// 事件 使用 addEventListener() 或将一个事件监听器赋值给本接口的 oneventname 属性,来监听下面的事件
// 当一个 WebSocket 连接被关闭时触发。
// 也可以通过 onclose 属性来设置。
"close" 
// 当一个 WebSocket 连接因错误而关闭时触发,例如无法发送数据时。
// 也可以通过 onerror 属性来设置。
"error" 
//  当通过 WebSocket 收到数据时触发。
// 也可以通过 onmessage 属性来设置。
"message"
// 当一个 WebSocket 连接成功时触发。
// 也可以通过 onopen 属性来设置。
"open" 

// 方法 调用该方法执行一些功能
// 关闭当前链接。
WebSocket.close([code[, reason]])
// 对要传输的数据进行排队。
// data类型:utf-8字符串、arraybuffer、blob、arraybufferview
WebSocket.send(data)

向服务器发送数据

发送文本:ws.send('your message');
发送二进制:

var file = document
  .querySelector('input[type="file"]')
  .files[0];
ws.send(file);

发送arraybuffer:

var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
  binary[i] = img.data[i];
}
ws.send(binary.buffer);

判断发送进度:实例对象的bufferedAmount属性,表示还有多少字节的二进制数据没有发送出去。它可以用来判断发送是否结束。

var data = new ArrayBuffer(10000000);
socket.send(data);

if (socket.bufferedAmount === 0) {
  // 发送完毕
} else {
  // 发送还没结束
}

处理服务器发过来的数据

发送过来的数据包裹在event.data

ws.onmessage = function(event) {
  var data = event.data;
  // 处理数据
};

ws.addEventListener("message", function(event) {
  var data = event.data;
  // 处理数据
});

对于接受的数据,需要判断下是什么类型,然后做处理

ws.onmessage = function(event){
  if(typeof event.data === String) {
    console.log("Received data string");
  }

  if(event.data instanceof ArrayBuffer){
    var buffer = event.data;
    console.log("Received arraybuffer");
  }
}

可以显式指定二进制的数据类型

// 收到的是 blob 数据 // 收到的是 ArrayBuffer 数据
ws.binaryType = "blob";//ws.binaryType = "arraybuffer";
ws.onmessage = function(e) {
  console.log(e.data.size);
};

一个完整示例

客户端:

;(function(){
  // 获取页面dom节点
  const domList = document.querySelector("#list");
  const domMsg = document.querySelector("#msg");
  const domSend = document.querySelector("#send");
  // 判断登陆状况
  const username = localStorage.getItem('username');
  if(username == null || username == ""){
    location.href = '/entry.html';
    return;
  }
  // 连接服务器
  const ws = new WebSocket("ws:localhost:8000");
  function init(){
    bindEvent();
  }
  // 绑定websocket事件
  function bindEvent(){
    domSend.addEventListener('click',handleSendMsg,false);
    ws.addEventListener('open',onOpen,false);
    ws.addEventListener('close',onClose,false);
    ws.addEventListener('error',onError,false);
    ws.addEventListener('message',onMessage,false); // 也可以: ws.onmessage = onMessage;
  }
  // 发送数据函数
  function handleSendMsg(){
    ws.send(JSON.stringify({
      "username":username,
      "msg":domMsg.value,
      "time":new Date()
    }))
    domMsg.value = "";
  }
  function onOpen(){
    console.log('open')
  }
  function onClose(){
    console.log('close')
  }
  function onError(){
    console.log('error')
  }
  // 接收数据并处理的函数,这里主要是将接收到的数据插入一个li标签到页面上
  function onMessage(e){
    console.log('message',e)
    domList.appendChild(createMsg(JSON.parse(e.data)))
  }
  function createMsg(data){
    const {username,msg,time} = data;
    const li = document.createElement('li');
    li.innerHTML = `
      <p><span>${username}</span>  <i>${time}</i></p>
      <p>${msg}</p>
    `
    return li;
  }

  init();
})();

服务器:这里使用ws包来监听

const WS = require("ws");
(function () {
  const server = new WS.Server({ port: 8000 });
  function init() {
    bindEvent();
  }
  function bindEvent() {
    server.on("open", onOpen);
    server.on("close", onClose);
    server.on("error", onError);
    server.on("connection", onConnection);
  }
  function onOpen() {
    console.log("open");
  }
  function onClose() {
    console.log("close");
  }
  function onError() {
    console.log("error");
  }
  function onMessage(msg) {
    console.log("message", JSON.parse(msg));
    server.clients.forEach((c) => c.send(msg, { binary: false }));
  }
  function onConnection(clinet) {
    console.log("connection");
    clinet.on("message", onMessage);
  }
  init();
})();

后端可以使用nodemon来监控这个index.js文件,并启动服务!
前端可以使用vite来启动服务!

// 后端
"scripts": {
    "dev": "nodemon index.js"
  },
// 前端
"scripts": {
    "dev":"vite"
  },
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:57:20  更:2022-07-17 16:59:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:27:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码