Websocket的基本认识、使用与封装

目录

一、Websocket是什么

二、Websocket的基本使用

使用介绍

第一步

第二步

第三步

第四步

常用API介绍 

WebSocket(url[, protocols])

WebSocket.readyState

 WebSocket.send(data)

WebSocket.close([code[, reason]])

WebSocket.bufferedAmount

WebSocket.extensions

WebSocket.binaryType

三、Websocket的封装

vue代码

react代码


一、Websocket是什么

        当一个Web应用程序需要实现实时双向通信时,传统的 HTTP 协议并不是最佳选择,因为HTTP是一个请求/响应协议,它的工作方式是客户端发送一个请求给服务器,服务器然后响应该请求,并发送一个响应给客户端。这种模式通常是单向的,客户端只能发起请求,而服务器只能响应请求。这意味着,客户端无法在不发出新请求的情况下接收来自服务器的新数据。

        WebSocket 协议就是为了解决这个问题而产生的,它可以在客户端和服务器之间建立持久的连接,以便实现双向通信。在建立连接之后,客户端和服务器可以随时发送消息,而不需要通过HTTP请求/响应的方式进行通信。此外,WebSocket还支持二进制数据的传输,这使得它更加灵活,可以用于许多不同的应用程序场景。

WebSocket协议的工作方式如下:

  1. 客户端向服务器发起一个WebSocket握手请求。这个请求与HTTP请求非常相似,但包含了一些附加的头部信息,以表示这是一个WebSocket请求。
  2. 服务器对该请求进行响应,包含一个状态码和一些头部信息。这个响应是HTTP响应,但同样包含了一些附加的头部信息,以表示这是一个WebSocket响应。
  3. 客户端和服务器之间的连接现在已经建立,并且可以进行双向通信了。客户端和服务器都可以随时发送消息,这些消息会被封装为WebSocket帧并通过WebSocket连接进行传输。

        需要注意的是,WebSocket协议与传统的HTTP协议不同,因为它不是基于请求/响应模式的。这意味着,一旦连接建立,客户端和服务器就可以随时发送消息,而不需要等待对方先发出请求。此外,WebSocket协议还支持心跳包机制,可以检测连接是否还处于活动状态。

        总之,WebSocket协议提供了一种高效、可靠、灵活的方式来实现Web应用程序之间的实时双向通信。它是一个强大的工具,可以用于许多不同的应用程序场景,包括在线游戏、实时聊天、数据传输和多人协作等等。

二、Websocket的基本使用

使用介绍

        前端使用WebSocket通常需要使用浏览器提供的WebSocket API,该API可以通过JavaScript代码与WebSocket服务器建立连接,并在连接建立后进行数据传输。

第一步

        创建一个WebSocket对象。可以使用以下代码创建一个WebSocket对象:

const socket = new WebSocket('ws://localhost:8080');

        在创建WebSocket对象时,需要传递WebSocket服务器的地址和端口号作为参数。WebSocket服务器地址可以使用ws://wss://前缀表示,ws://表示使用普通的HTTP协议进行通信,wss://表示使用加密的HTTP协议进行通信。

第二步

        监听WebSocket事件。WebSocket API提供了几种事件类型,可以通过这些事件来处理WebSocket的连接状态和数据传输。下面是常用的事件类型:

  • open:WebSocket连接成功时触发。
  • message:接收到WebSocket服务器发送的消息时触发。
  • error:WebSocket连接出错时触发。
  • close:WebSocket连接关闭时触发。

可以使用下面的代码监听WebSocket事件:

socket.addEventListener('open', (event) => {console.log('WebSocket连接已打开');
});socket.addEventListener('message', (event) => {console.log('接收到消息:', event.data);
});socket.addEventListener('error', (event) => {console.log('WebSocket连接出错:', event);
});socket.addEventListener('close', (event) => {console.log('WebSocket连接已关闭');
});

第三步

        发送数据。可以使用WebSocket.send()方法向WebSocket服务器发送数据。该方法接受一个字符串或一个二进制数据对象作为参数。下面是一个例子: 

        这里需要注意的是如果传输的数据为对象格式,应转换为JOSN格式进行传输。  

socket.send('Hello, WebSocket!');

第四步

        关闭连接。可以使用WebSocket.close()方法关闭WebSocket连接。

socket.close();

常用API介绍 

WebSocket(url[, protocols])

        创建WebSocket对象。其中,url参数是WebSocket服务器的地址,protocols参数是一个可选的字符串或字符串数组,表示WebSocket协议的子协议列表。(见使用介绍第一步)

WebSocket.readyState

        WebSocket对象的只读属性,表示当前WebSocket的连接状态,它的值为下面四个之一:

  • 0 - 表示WebSocket连接尚未建立。
  • 1 - 表示WebSocket连接已建立,可以进行通信。
  • 2 - 表示WebSocket连接正在关闭。
  • 3 - 表示WebSocket连接已经关闭或者连接不能打开。
console.log(this.webSocket.readyState)

 WebSocket.send(data)

        向WebSocket服务器发送数据。其中,data参数可以是一个字符串、一个二进制数据对象或者一个Blob对象。(见使用介绍第三步)

WebSocket.close([code[, reason]])

关闭WebSocket连接。其中,code参数表示关闭代码,reason参数表示关闭原因。(见使用介绍第四步)

WebSocket.bufferedAmount

        WebSocket的bufferedAmount属性表示已经被send()方法发送但还没有被发送到网络层的数据量。在发送数据的过程中,如果发送的数据量大于WebSocket的缓冲区大小,那么这些数据就会被暂时保存在WebSocket的缓冲区中,直到网络层可以接受这些数据时再发送出去。

const socket = new WebSocket('ws://localhost:8080');
console.log('初始bufferedAmount:', socket.bufferedAmount);
socket.send('Hello, WebSocket!');
console.log('发送后bufferedAmount:', socket.bufferedAmount);

WebSocket.extensions

        WebSocket的extensions属性是一个只读属性,它表示WebSocket服务器支持的扩展列表。

const socket = new WebSocket('ws://localhost:8080');
console.log('WebSocket服务器支持的扩展:', socket.extensions);

WebSocket.binaryType

        WebSocket的binaryType属性表示在收到二进制数据时使用的编码方式,默认值是"blob"。可以将其设置为"arraybuffer"来使用ArrayBuffer对象来处理二进制数据。

const socket = new WebSocket('ws://localhost:8080');
socket.binaryType = 'arraybuffer';
socket.addEventListener('message', (event) => {const arrayBuffer = event.data;// 处理二进制数据
});

三、Websocket的封装

vue代码

import Vue from 'vue'
import { Message } from 'element-ui'
let v = new Vue()
v.$message = Message;
var webSocket = null;
var isConnect = false; //连接状态
var globalCallback = function(e){ console.log(e) };//定义外部接收数据的回调函数
var reConnectNum = 0;//重连次数var websocketUrl =  process.env.VUE_APP_API_WEBSOCKET_URL;//心跳设置
var heartCheck = {heartbeatData:{DevID:{value:Vue.ls.get('devid')},DevHeart:{value:"1"}   },//心跳包timeout: 60 * 1000, //每段时间发送一次心跳包 这里设置为60sheartbeat: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)start: function () {this.heartbeat = setInterval(()=>{if (isConnect){webSocketSend(this.heartbeatData);}else{this.clear();}}, this.timeout);},reset: function () {clearInterval(this.heartbeat);this.start();},clear:function(){clearInterval(this.heartbeat);}
}//初始化websocket
function initWebSocket(callback) {//此callback为在其他地方调用时定义的接收socket数据的函数if(callback){if(typeof callback == 'function'){globalCallback = callback     }else{throw new Error("callback is not a function")}}if ("WebSocket" in window) {webSocket = new WebSocket(websocketUrl);//创建socket对象} else {Message({message: '该浏览器不支持websocket!',type: 'warning'});return}//打开webSocket.onopen = function() {webSocketOpen();};//收信webSocket.onmessage = function(e) {webSocketOnMessage(e);};//关闭webSocket.onclose = function(e) {webSocketOnClose(e);};//连接发生错误的回调方法webSocket.onerror = function(e) {webSocketonError(e);};
}//连接socket建立时触发
function webSocketOpen() {console.log("WebSocket连接成功");//首次握手webSocketSend(heartCheck.heartbeatData);isConnect = true;heartCheck.start();reConnectNum = 0;
}//客户端接收服务端数据时触发,e为接受的数据对象
function webSocketOnMessage(e) {console.log("websocket信息:");console.log(e.data)const data = JSON.parse(e.data);//根据自己的需要对接收到的数据进行格式化globalCallback(data);//将data传给在外定义的接收数据的函数,至关重要。
}//socket关闭时触发
function webSocketOnClose(e){heartCheck.clear();isConnect = false; //断开后修改标识console.log(e)console.log('webSocket已经关闭 (code:' + e.code + ')')//被动断开,重新连接if(e.code == 1006){if(reConnectNum < 3){initWebSocket();++reConnectNum;}else{v.$message({message: 'websocket连接不上,请刷新页面或联系开发人员!',type: 'warning'});}}
}//连接发生错误的回调方法
function webSocketonError(e){heartCheck.clear();isConnect = false; //断开后修改标识console.log("WebSocket连接发生错误:");console.log(e);
}//发送数据
function webSocketSend(data) {webSocket.send(JSON.stringify(data));//在这里根据自己的需要转换数据格式
}
//在其他需要socket地方主动关闭socket
function closeWebSocket(e) {webSocket.close();heartCheck.clear();isConnect = false;reConnectNum = 0;
}
//在其他需要socket地方接受数据
function getSock(callback) {globalCallback = callback
}
//在其他需要socket地方调用的函数,用来发送数据及接受数据
function sendSock(agentData) {//下面的判断主要是考虑到socket连接可能中断或者其他的因素,可以重新发送此条消息。switch (webSocket.readyState) {//CONNECTING:值为0,表示正在连接。case webSocket.CONNECTING:setTimeout(function() {sendSock(agentData, callback);}, 1000);break;//OPEN:值为1,表示连接成功,可以通信了。case webSocket.OPEN:webSocketSend(agentData);break;//CLOSING:值为2,表示连接正在关闭。case webSocket.CLOSING:setTimeout(function() {sendSock(agentData, callback);}, 1000);break;//CLOSED:值为3,表示连接已经关闭,或者打开连接失败。case webSocket.CLOSED:// do somethingbreak;default:// this never happensbreak;}
}export default {initWebSocket,closeWebSocket,sendSock,getSock
};

vue方法来自于这位大佬的文章,以下是链接。websocket封装_Paul_Chan_的博客-CSDN博客websocket封装https://blog.csdn.net/weixin_43422861/article/details/114259139?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168336616716782425125574%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168336616716782425125574&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-1-114259139-null-null.142%5Ev86%5Einsert_down28,239%5Ev2%5Einsert_chatgpt&utm_term=websocket%E5%B7%A5%E5%85%B7%E5%B0%81%E8%A3%85&spm=1018.2226.3001.4187

react代码

import React, { Component } from 'react';class WebSocketHelper extends Component {constructor(props) {super(props);this.state = {websocket: null,heartBeatIntervalId: null,};}componentDidMount() {this.connectWebSocket();}componentWillUnmount() {this.closeWebSocket();}connectWebSocket = () => {const websocket = new WebSocket(this.props.url);websocket.onopen = () => {console.log('WebSocket connection opened.');this.props.onOpen && this.props.onOpen();if (this.props.heartBeatInterval) {const heartBeatIntervalId = setInterval(() => {console.log('Sending WebSocket heartbeat.');this.sendMessage(this.props.heartBeatMessage);}, this.props.heartBeatInterval);this.setState({ heartBeatIntervalId });}};websocket.onclose = () => {console.log('WebSocket connection closed.');this.props.onClose && this.props.onClose();if (this.state.heartBeatIntervalId) {clearInterval(this.state.heartBeatIntervalId);this.setState({ heartBeatIntervalId: null });}setTimeout(() => {console.log('Attempting to reconnect WebSocket.');this.connectWebSocket();}, this.props.reconnectInterval || 5000);};websocket.onerror = (error) => {console.error('WebSocket error:', error);this.props.onError && this.props.onError(error);};websocket.onmessage = (event) => {console.log('WebSocket message received:', event.data);this.props.onMessage && this.props.onMessage(event.data);};this.setState({ websocket });}closeWebSocket = () => {if (this.state.websocket) {this.state.websocket.close();console.log('WebSocket connection closed.');if (this.state.heartBeatIntervalId) {clearInterval(this.state.heartBeatIntervalId);this.setState({ heartBeatIntervalId: null });}}}sendMessage = (message) => {if (this.state.websocket) {console.log('Sending WebSocket message:', message);this.state.websocket.send(message);}}render() {return this.props.render({sendMessage: this.sendMessage,closeWebSocket: this.closeWebSocket,});}
}export default WebSocketHelper;

使用

import React from 'react';
import WebSocketHelper from './WebSocketHelper';function App() {const handleOpen = () => {console.log('WebSocket connection opened.');};const handleClose = () => {console.log('WebSocket connection closed.');};const handleError = (error) => {console.error('WebSocket error:', error);};const handleMessage = (message) => {console.log('WebSocket message received:', message);};const handleRender = ({ sendMessage, closeWebSocket }) => {// 这里可以使用 sendMessage 和 closeWebSocket 方法return (<div><button onClick={() => sendMessage('Hello WebSocket!')}>Send Message</button><button onClick={() => closeWebSocket()}>Close WebSocket</button></div>);};return (<WebSocketHelperurl="wss://example.com"onOpen={handleOpen}onClose={handleClose}onError={handleError}onMessage={handleMessage}render={handleRender}/>);
}export default App;

           更多详细信息详见官网:https://www.websocket.org/https://www.websocket.org/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/72163.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

asp.net paypal信用卡支付功能

前段时间有个客户网站需要用到信用卡支付功能&#xff0c;客户有个Website Payments Pro的帐号&#xff0c;第一次做这东西花了很多时间在上面&#xff0c;已做好运行了一段日子&#xff0c; 现在总结一下&#xff1a; 1. 先注册一个paypal开发者帐号&#xff0c;这个主要用于s…

通义听悟诞生背后,AI大模型打响应用第一枪

配图来自Canva可画 2023年伊始&#xff0c;ChatGPT的爆火出圈&#xff0c;迅速引发了业界对于生成式AI应用的关注&#xff0c;AI大模型的竞争更是愈演愈烈。 作为参与其中的重要玩家&#xff0c;阿里云先是在4月11日举行的阿里云峰会上&#xff0c;推出了通义千问大模型。紧接…

开发私有chatGPT(二)openai前景展望

使用 OpenAI 的强大模型构建下一代应用程序。 GPT-3可以执行各种自然语言任务、Codex 可以将自然语言转换为代码的 &#xff0c;DALLE&#xff0c;用于创建和编辑原始图像。 DALLE 开发人员现在可以开始使用&#xff0c;已经有超过3万人已经在使用DALLE来扩展他们的创造力并加…

快给你的对象做一个微信公众号播报吧-java版

一、前期准备 1.注册微信测试公众号 使用微信扫码登录此网站https://mp.weixin.qq.com/debug/cgi-bin/sandbox?tsandbox/login就能得到一个微信公众号测试号 推送消息需要用到的信息 用户扫码关注得到用户的id 编辑消息模板 此步骤的模板id、用户微信号id、以及自己的appID、…

2013年10月微软MVP当选名单揭晓!

微软公司于2001年8月起开始在亚洲与各大主要的第三方网站上的微软技术相关论坛合作&#xff0c;微软称之为“亚洲社区支持”计划。 为了鼓励大家在论坛中更好地互相帮助&#xff0c;共同提高&#xff0c;微软在全亚洲的微软论坛参与者中评选出那些技术水平高&#xff0c;积…

八大排序·希尔排序

大家好&#xff0c;我是安然无虞。 文章目录 希尔排序1.基本思想预排序 2.算法实现3.时间复杂度 遇见安然遇见你&#xff0c;不负代码不负卿。 插入排序分为两种&#xff1a;直接插入排序&希尔排序 希尔排序 1.基本思想 希尔排序是在直接插入排序基础上的优化&#xff0c…

十大排序之希尔排序

希尔排序 希尔排序(Shell Sort)是插入排序的一种算法&#xff0c;是对直接插入排序的一个优化&#xff0c;也称缩小增量排序。 希尔排序是非稳定排序算法。 希尔排序因DL&#xff0e;Shell于1959年提出而得名。 希尔排序是将待排序的数组元素按下标的一定增量分组 &#xff…

NBA球员出手位置分布图

小白一只&#xff0c;想转行互联网行业的数据分析&#xff0c;通过寒假的佛系学习对python有了一定的了解。记录一下第一个小玩意儿。 在刷crossin论坛的时候突然看到一篇关于NBA的数据分析&#xff0c;因为本身自己也非常喜欢打球&#xff0c;顿时就有了兴趣。 由于对python…

【八大排序(二)】希尔排序(谁说天才都短命?)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:八大排序专栏⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习排序知识   &#x1f51d;&#x1f51d; Shell排序 1. 前言&#x1f6a9;2. 希尔排…

网络安全工程师需要考什么证吗?

目前网络安全行业&#xff0c;国内都有哪些证书可以考。 一、CISP-PTE &#xff08;国家注册渗透测试工程师&#xff09; CISP-PTE即注册信息安全渗透测试工程师&#xff0c;该证书由中国信息安全测评中心颁发&#xff0c;证书是国内唯一认可的渗透测试认证&#xff0c;专业性…

网络安全有哪些岗位?如何成为一名优秀的网络安全工程师?

网络安全是什么&#xff1f; 首先说一下什么是网络安全&#xff1f;其中&#xff0c;网络安全工程师工作内容具体有哪些&#xff1f; 网络安全 确保网络系统的硬件、软件及其系统中的数据受到保护&#xff0c;不因偶然的或者恶意的原因而受到破坏、更改、泄露&#xff0c;系统…

为什么说,网络安全工程师是网安行业的天花板?

为什么说&#xff0c;网络安全工程师是网安行业的天花板&#xff1f; 最近看到网上有很多人在问诸如&#xff1a;“怎样成为网络信息安全工程师”等相关问题&#xff0c;甚至还有人说“网络安全工程师已经成为这个行业的天花板”&#xff0c;这可能与近几年网络安全事件频发&a…

网络安全工程师必备的七大技能

网络安全有多重要 网络安全非常重要&#xff0c;因为在现代社会中&#xff0c;人们日常生活中的很多方面都与网络有关。随着互联网和数字技术的不断发展&#xff0c;人们已经变得越来越依赖网络&#xff0c;网络已经成为了商业、金融、通信、交通、能源、医疗、教育等各个领域…

软考网络工程师

网络工程师备考经验 2022年上半年网络工程师的考试已经接近尾声&#xff0c;成绩也在7月23号出来了&#xff0c;本人运气很好&#xff0c;在这次考试中取到了满意的成绩&#xff0c;下面是查询结果。 配套资料&#xff1a; 链接: https://pan.baidu.com/s/1b486ZUOYpjsNN-9oK…

网络安全工程师是做什么的?

顾名思义&#xff0c;网络安全工程师主要是维护网络的安全和稳定&#xff0c;对网页篡改、计算机病毒、系统非法入侵、数据泄密、网站欺骗、服务瘫痪、漏洞非法利用等信息安全事件进行维护。从社会角度来看&#xff0c;网络安全工程师在维护个人信息安全和解开黑客攻击上发挥着…

网络安全有哪些岗位,如何成为一位优秀的网络安全工程师?

网络安全是什么&#xff1f; 首先说一下什么是网络安全&#xff1f; 网络安全工程师工作内容具体有哪些&#xff1f; 网络安全是确保网络系统的硬件、软件及其系统中的数据受到保护&#xff0c;不因偶然的或者恶意的原因而受到破坏、更改、泄露&#xff0c;系统连续可靠正常地…

网络安全工程师和网络工程师一样吗(网络安全工程师与网络工程师)

前言 今天给各位分享网络安全工程师和网络工程师一样吗的知识&#xff0c;其中也会对网络安全工程师与网络工程师进行解释&#xff0c;如果能碰巧解决你现在面临的问题&#xff0c;别忘了关注本站&#xff0c;现在开始吧&#xff01;本文目录一览&#xff1a; 1、网络工程师、网…

如何成为一名合格的网络安全工程师?需要掌握那些能力?

近期网络的迅速发展&#xff0c;网络安全成为了一个备受关注的话题。随之而来的是网络安全工程师这个职业的兴起。成为一名合格的网络安全工程师需要具备哪些能力呢&#xff1f;下面我们来一一探讨。 首先 网络安全技术方面是网络安全工程师必须掌握的能力之一。网络安全技术…

网络安全工程师考证指南

已经到2023年了&#xff0c;那么信息安全类证书最有前途的有哪些呢&#xff1f;今天和大家一起聊聊这个话题&#xff01; 1.CISP(国家登记的信息安全专业人员) 就CISP而言&#xff0c;安全实践者基本耳闻&#xff0c;算是国内权威认证&#xff0c;毕竟有政府背景为认证做背书…

网络安全工程师需要具备的5个重要技能

网络安全工程师需要具备的5个重要技能 大数据时代&#xff0c;网络安全非常重要&#xff0c;越来越多的企业也越来越重视网络安全&#xff0c;而网络安全工程师也成为现在需求量比较大的职业&#xff0c;成都也有很多专门做网络安全培训的学校&#xff0c;为这个行业的发展输送…