实现服务端和客户端的实时双向数据传输-WebSocket简单了解
WebSocket
前段时间项目中遇到了消息推送的问题,当时采用客户端轮询,每隔 5s 请求一次数据。由于轮询的效率低,非常浪费资源。后面准备把轮询调整为使用 WebSocket 来建立连接,实现推送。
WebSocket 介绍
一种网络通信协议,使用 WebSocket 服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,实现真正的双向平等对话,可以实现服务器推送功能。并且现在浏览器中都已实现。
与 HTTP 比对
HTTP 协议,通信只能客户端发起。
比如:在接收提示消息时,只能客户端向服务器端发送请求才知道有没有最新的消息。不能服务器端直接通知客户端有最新的消息。简单来说就是 HTTP 做不到信息的推送。只能通过客户端每隔一段时间发送请求查询。
而 HTTP2.0 则是对 HTML、CSS 等 JS 资源的传输方式进行了优化,并没有提供新的 JS API,也不能用于实时传输消息。
WebSocket 特点
客户端与服务器端实现容易(建立在 TCP 协议之上)
没有同源限制可以与任意服务器建立通信
协议表示符为 ws 或者 wws(加密协议),服务器地址就是 url 地址
- 比如:
ws://demo.example.com:8001
- 比如:
客户端使用
在客户端中使用很简单,只需要开启一个 WebSocket 服务并且实现监听服务器发送的消息即可。
// 开启WebSocket服务
var ws = new WebSocket("ws://127.0.0.1:8001");
ws.onopen = function (data) {
// 发送信息
ws.send("hello World");
};
ws.onmessage = function (data) {
console.log(data.data); // 接收信息
};
ws.onclose = function (data) {
console.log("关闭", data); //关闭
};
如上代码,我们可以使用 ws.send()发送数据,也可以适用 ws.onmessage 监听服务器端发送的信息数据,实现简单的实时双向传输功能。
WebSocket 事件
我们在开始 WebSocket 服务之后,可以直接使用 addEventListener() 或将一个事件监听器赋值给接口的 oneventname 属性,来监听相关事件。
clone
当一个 WebSocket 连接被关闭时触发。
也可以通过 onclose 属性来设置。
ws.addEventListener("clone", function (event) {
// WebSocket 已关闭
});
//或者
ws.onclone = function (event) {
// WebSocket 已关闭
};
如上面代码所示,WebSocket 的相关事件都可以通过这两种方法来监听实现。
error
当一个 WebSocket 连接因错误而关闭时触发,例如无法发送数据时。
也可以通过 onerror 属性来设置.
ws.addEventListener("error", function (event) {
// WebSocket 出现错误
});
//或者
ws.onerror = function (event) {
// WebSocket 出现错误
};
message
当通过 WebSocket 收到数据时触发。
也可以通过 onmessage 属性来设置。
ws.addEventListener("message", function (event) {
// WebSocket 监听消息 收到服务器端消息是触发
});
//或者
ws.onmessage = function (event) {
// WebSocket 监听消息 收到服务器端消息是触发
};
open
当一个 WebSocket 连接成功时触发。
也可以通过 onopen 属性来设置。
ws.addEventListener("open", function (event) {
// WebSocket 连接成功。
});
//或者
ws.onopen = function (event) {
// WebSocket 连接成功。
};
客户端属性与方法
WebSocket.readyState
该属性返回当前的实例对象状态(只读):
- CONNECTING:值为 0,正在链接中
- OPEN:值为 1,已经链接并且可以通讯
- CLOSING:值为 2,连接正在关闭
- CLOSED:值为 3,连接已关闭或者没有链接成功
WebSocket.bufferedAmount
未发送至服务器的字节数(只读)。当 WebSocket.bufferedAmount 为 0 时说明发送成功。在实际项目中可以该属性来判断是否发送完成。
if (ws.bufferedAmount === 0) {
// 发送成功
} else {
// 发送未结束
}
其他属性
- WebSocket.url WebSocket 的绝对路径(只读)。
- WebSocket.protocol 服务器选择的下属协议(只读)。
- WebSocket.extensions 返回服务器已选择的扩展值。目前,链接可以协定的扩展值只有空字符串或者一个扩展列表(只读)。
- WebSocket.binaryType 返回 websocket 连接所传输二进制数据的类型。
WebSocket.send()
对要传输的数据进行排队。
WebSocket.send() 方法将需要通过 WebSocket 链接传输至服务器的数据排入队列,并根据所需要传输的 data bytes 的大小来增加 bufferedAmount 的值 。若数据无法传输(例如数据需要缓存而缓冲区已满)时,套接字会自行关闭。
发送数据类型需是下面几个类型之一:
- USVString:文本字符串,字符串将以 UTF-8 格式添加到缓冲区,并且 bufferedAmount 将加上该字符串以 UTF-8 格式编码时的字节数的值。
- ArrayBuffer:可以使用一有类型的数组对象发送底层二进制数据;其二进制数据内存将被缓存于缓冲区,bufferedAmount 将加上所需字节数的值。
- Blob:Blob 类型将队列 blob 中的原始数据以二进制中传输。 bufferedAmount 将加上原始数据的字节数的值。
- ArrayBufferView:可以以二进制帧的形式发送任何 JavaScript 类数组对象 ;其二进制数据内容将被队列于缓冲区中。值 bufferedAmount 将加上必要字节数的值。
// 文本:
ws.send("hello world");
// ArrayBuffer
const buffer = new ArrayBuffer(8);
ws.send(buffer);
// Blob
var demo = { hello: "world" };
var blob = new Blob([JSON.stringify(demo, null, 2)], {
type: "application/json",
});
ws.send(blob);
WebSocket.close()
关闭当前链接。
两个可选参数:
- code: 可选,一个数字状态码,它解释了连接关闭的原因。如果没有传这个参数,默认使用 1005
- reason: 可选,可读的字符串,它解释了连接关闭的原因。
事件类型
- WebSocket.onclose 用于指定连接关闭后的回调函数。
- WebSocket.onerror 用于指定连接失败后的回调函数。
- WebSocket.onmessage 用于指定当从服务器接受到信息时的回调函数。
- WebSocket.onopen 用于指定连接成功后的回调函数。
服务端使用
如果各个服务器端语言实现方法不一样,这里简单说下我的测试环境。
测试使用的是 node.js 配合 nodejs-websocket 进行的
具体使用如下:
// 引入nodejs-websocket
var ws = require("nodejs-websocket");
// 创建websocket
var server = ws
.createServer(function (conn) {
// 监听消息
conn.on("text", function (str) {
// 调用相关方法
loadMessage(conn, str);
});
// 监听关闭
conn.on("close", function (code, reason) {
console.log("关闭");
});
})
.listen(8001);
console.log("开启成功~");
// 接收消息 并返回信息
function loadMessage(conn, str) {
conn.send(str + "获取到消息,已接收消息,已返回回答");
}
最后附上运行截图
开启服务器端WebSocket:

客户端运行:

当服务器关闭服务:

实现服务端和客户端的实时双向数据传输-WebSocket简单了解的更多相关文章
- openssl实现双向认证教程(服务端代码+客户端代码+证书生成)
一.背景说明 1.1 面临问题 最近一份产品检测报告建议使用基于pki的认证方式,由于产品已实现https,商量之下认为其意思是使用双向认证以处理中间人形式攻击. <信息安全工程>中接触过 ...
- 使用flask_socketio实现服务端向客户端定时推送
websocket连接是客户端与服务器之间永久的双向通信通道,直到某方断开连接. 双向通道意味着在连接时,服务端随时可以发送消息给客户端,反之亦然,这在一些需要即时通讯的场景比如多人聊天室非常重要. ...
- C#在服务端验证客户端证书(Certificate)
使用https协议进行通讯的时候可以设置双向证书认证,客户端验证服务端证书的方法前面已经介绍过了,现在说一下在服务端验证客户端证书的方案. 这里给出的方案比较简单,只需要在Service端的配置文件中 ...
- 采用MQTT协议实现android消息推送(2)MQTT服务端与客户端软件对比、android客户端示列表
1.服务端软件对比 https://github.com/mqtt/mqtt.github.io/wiki/servers 名称(点名进官网) 特性 简介 收费 支持的客户端语言 IBM MQ 完整的 ...
- Centos6.9 搭建rsync服务端与客户端 案例:全网备份项目
rsync的企业工作场景说明 1)定时备份 1.1生产场景集群架构服务器备份方案项目 借助cron+rsync把所有客户服务器数据同步到备份服务器 2)实时复制 本地数据传输模式(local-only ...
- 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
常量,字段,构造方法 常量 1.什么是常量 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...
- 基于SignalR的服务端和客户端通讯处理
SignalR是一个.NET Core/.NET Framework的实时通讯的框架,一般应用在ASP.NET上,当然也可以应用在Winform上实现服务端和客户端的消息通讯,本篇随笔主要基于Sign ...
- 使用WebSocket实现服务端和客户端的通信
开发中经常会有这样的使用场景.如某个用户在一个数据上做了xx操作, 与该数据相关的用户在线上的话,需要实时接收到一条信息. 这种可以使用WebSocket来实现. 另外,对于消息,可以定义一个类进行固 ...
- 【.NET+MQTT】.NET6 环境下实现MQTT通信,以及服务端、客户端的双边消息订阅与发布的代码演示
前言: MQTT广泛应用于工业物联网.智能家居.各类智能制造或各类自动化场景等.MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,在很多受限的环境下,比如说机器与机器通信.机器与物联网通信等. ...
随机推荐
- js实现element中可清空的输入框(2)
接着上一篇的:js实现element中可清空的输入框(1)继续优化,感兴趣的可以去看看哟,直通车链接:https://www.cnblogs.com/qcq0703/p/14450001.html 实 ...
- WPF -- 一种添加静态资源的方式
本文介绍使用独立的xaml文件添加静态资源的方式. 步骤 创建XAML文件,如ImageButton.xaml,添加ResourceDictionary标签,并添加静态资源: 在App.xaml的Ap ...
- 解决 DatePickerDialog 在 Android7.0 API24 上使用 AlertDialog.THEME_TRADITIONAL、AlertDialog.THEME_HOLO_DARK、AlertDialog.THEME_HOLO_LIGHT等样式时无法显示为 Spinner 样式的问题
DatePickerDemoForAndroid24 解决 DatePickerDialog 在 Android7.0 API24 上使用AlertDialog.THEME_TRADITIONAL.A ...
- 人脸检测数据源制作与基于caffe构架的ALEXNET神经网络训练
本篇文章主要记录的是人脸检测数据源制作与ALEXNET网络训练实现检测到人脸(基于caffe). 1.数据获取 数据获取: ① benchmark是一个行业的基准(数据库.论文.源码.结果),例如WI ...
- 大家最常用的编程论坛是哪个呢,欢迎评论!!掘金16 juejin 简书41 jianshu 博客85 csdn137 csdn
软件编程交流论坛 掘金 16 juejin 简书 41 jianshu 博客 85 cnblogs csdn 137 csdn stackoverflow 0 思否 github 大家最常用的 ...
- MySql学习---数据库基本类型,事务,多表查询
数据库分类 关系型数据库 行列, 列如Mysql,oracle 通过表和表之间,行和列之间的关系进行数据的存储 非关系型数据库: Redis,MongDb 以对象存储,同过对象的自身属性来决定 表与表 ...
- Shiro 反序列化漏洞利用
环境搭建 docker pull medicean/vulapps:s_shiro_1 docker run -d -p 80:8080 medicean/vulapps:s_shiro_1 # 80 ...
- go中errgroup源码解读
errgroup 前言 如何使用 实现原理 WithContext Go Wait 错误的使用 总结 errgroup 前言 来看下errgroup的实现 如何使用 func main() { var ...
- Java数据持久层
一.前言 1.持久层 Java数据持久层,其本身是为了实现与数据源进行数据交互的存在,其目的是通过分层架构风格,进行应用&数据的解耦. 我从整体角度,依次阐述JDBC.Mybatis.Myba ...
- Sentinel熔断降级
sentinel流量控制 Sentinel流量控制&服务熔断降级介绍 流量控制介绍 在这里我用景区的例子解释一下 一个旅游景点日接待游客数量为8K,8K以后的游客就无法买票进去景区. 对应编程 ...