WebSocket魔法师:打造实时应用的无限可能
1、背景
在开发一些前端页面的时候,总是能接收到这样的需求:如何保持页面并实现自动更新数据呢?以往的常规做法,是前端使用定时轮询后端接口,获取响应后重新渲染前端页面,这种做法虽然能达到类似的效果,但是依然有很多缺点,缺点就不在这里说了,感兴趣的小伙伴可以自行查阅一下。现在让我们回忆一下,我们有没有想过,是否有一种技术,服务器可以主动将数据推送给客户端进行渲染,而不再是客户端向服务器发出请求等待返回结果呢?接下来,让我们一起了解weboskcet。
2、什么是websocket
websocket是HTML5规范的一个部分,它借鉴了socket的思想,实现了浏览器与服务器全双工通信,达到了即时通信的效果。websocket协议基于TCP协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程,避免服务器频繁打开多个HTTP连接,从而能更好的节省服务器资源和带宽,提高工作效率与资源利用率
3、工作原理
websocket的通信规范,首先浏览器通过HTTP协议发出websocket的连线请求,服务器进行响应,这个过程称为握手,握手完成后,客户端和服务器之间建立一个类似TCP的连接,使用websocket协议,从而实现它们之间的通信。
4、与HTTP的关系
相同点:
1、都是基于TCP协议,且都是可靠性传输协议;
2、都是应用层协议;
3、websocket支持两种资源标志符ws(默认80端口)与wss(默认443端口),类似HTTP和HTTPS;
不同点:
1、websocket是双向通信协议,HTTP是单向的;
2、websocket是需要浏览器和服务器握手进行建立连接的,HTTP是浏览器发起向服务器的连接,服务器预先并不知道这个连接。
联系点:
websocket在建立握手时,数据是通过HTTP传输的,建立之后的数据传输将不再需要HTTP协议,而是websocket协议;
5、websocket创建与常用的属性方法
5.1 websocket属性
| 属性 | 描述 |
|---|---|
| readyState | 只读属性 readyState 表示连接状态,可以是以下值:0 :表示连接尚未建立。1 :表示连接已建立,可以进行通信。2 :表示连接正在进行关闭。3 :表示连接已经关闭或者连接不能打开。 |
| bufferedAmount | 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。 |
| CONNECTING | 值为0,表示正在连接 |
| OPEN | 值为1,表示连接已建立,可以进行通信 |
| CLOSING | 值为2,表示连接正在关闭 |
| CLOSED | 值为3,表示连接已经关闭或者连接不能打开 |
// 创建websocket
var ws = new WebSocket("ws://www.example.com");
if(ws.readyState == ws.CONNECTING){
console.log('连接正在打开');
}
ws.onopen = function () {
ws.send(consumerId);
if(ws.readyState == ws.CONNECTING){
console.log('连接正在打开1');
}
if(ws.readyState == ws.OPEN){
console.log('连接已打开');
}
console.log('已经建立连接');
// 关闭连接
// ws.close()
};
// 连接关闭时触发
ws.onclose = function () {
if(ws.readyState == ws.CLOSED){
console.log('连接已关闭')
}
};
// 连接错误
ws.onerror = function () {
console.log('连接错误');
};
5.2 weboscket事件
| 事件 | 处理程序 | 描述 |
|---|---|---|
| open | onopen | 连接建立时触发 |
| message | onmessage | 接收消息时触发 |
| error | onerror | 发生错误时触发 |
| close | onclose | 关闭连接时触发 |
5.3 客户端的简单示例
// 创建websocket
var ws = new WebSocket("ws://www.example.com");
// 连接成功时触发
ws.onopen = function(e) {
console.log("Connectiong open ...");
// 发送消息
ws.send("Hello WebSocket");
};
// 接收消息时触发
ws.onmessage = function(e) {
console.log("Received Message: " + e.data);
ws.close();
};
// 关闭连接时触发
ws.onclose = function(e) {
console.log("Connection closed");
};
// 出现错误时触发
ws.onerror = function(e) {
console.log("error");
};
5.4 服务端的简单示例
# 创建websocket服务端
from tornado.websocket import WebSocketHandler
class wsHandler(WebSocketHandler):
# 保存连接的用户,用于后续推送消息
connect_users = set()
# 已与客户端建立连接
def open(self):
print("开启WebSocket opened")
self.connect_users.add(self)
# 关闭客户端连接
def on_close(self):
self.connect_users.remove(self)
# 接收到消息
def on_message(self, message):
self.write_message("接收到客户端的消息:{}".format(message))
# 所有用户发送消息
@classmethod
def send_demand_updates(cls, message):
# 使用@classmethod可以使类方法在调用的时候不用进行实例化
# 给所有用户推送消息(此处可以根据需要,修改为给指定用户进行推送消息)
for user in cls.connect_users:
user.write_message(message)
# 允许WebSocket的跨域请求
def check_origin(self, origin):
return True
if __name__ == "__main__":
# 调用
wsHandler。send_demand_updates("服务端发送给客户端的消息")
注意:示例中使用python语言,需依托tornado框架搭建后端web服务端,文章中不再说明如何搭建服务端,感兴趣的小伙伴可自行尝试。tornado内置websocket模块,能更简单的支持使用websocket。
6、总结
websocket提供了一种低延迟、高性能的双向数据通信,不同与web开发的请求、处理、等待响应模式,它是客户端、服务端因为同一个连接直接就可以数据互传的模式,特别适合实时数据交互的应用进行开发。
实用点:
1、websocket连接建立后,后续的数据传输都将以帧序列的形式传输;
2、在客户端断开websocket连接或服务端中断连接前,不需要客户端和服务端重新发起连接请求;
3、在海量并发、客户端与服务器交互负载流量大的情况下,节省网络带宽资源的消耗,且客户端发送与接收消息,都是在同一个持久连接上进行,实现了“真长连接”,真正的实现即时通信。
作者:京东物流 骆铜磊
来源:京东云开发者社区 自猿其说Tech 转载请注明来源
WebSocket魔法师:打造实时应用的无限可能的更多相关文章
- Spring+WebSocket+SockJS实现实时聊天
设计初衷是通过websocket实现网页实时通讯聊天. 工程环境:tomcat8+jdk1.7+maven+eclipse 设计思路:客户端登录网页建立socket连接,后台记录用户连接信息并做标识: ...
- 远哥谈 使用WebSocket开发在线实时看远程服务器log日志的工具
我们开发软件的,通常会有一个测试环境/开发环境,但是系统开发完成后,还会有一个生产环境,也叫正式环境.正式环境我们一般是不能让开发人员去远程登录和维护的,一般正规的生产环境是专门的负责人员去负责更新, ...
- Vue+WebSocket 实现页面实时刷新长连接
最近vue项目要做数据实时刷新,折线图每秒重画一次,数据每0.5秒刷新一次,说白了就是实时刷新,因为数据量较大,用定时器估计页面停留一会就会卡死... 与后台人员讨论过后决定使用h5新增的WebSoc ...
- Node.js 打造实时多人游戏框架
在 Node.js 如火如荼发展的今天,我们已经可以用它来做各种各样的事情.前段时间UP主参加了极客松活动,在这次活动中我们意在做出一款让“低头族”能够更多交流的游戏,核心功能便是 Lan Party ...
- 转:打造DropDownList,TreeView,ListBox无限极分类目录树
[csharp] view plaincopyprint? #region DropDownList无限递归显示层次关系 /// <summary> /// 创建无限分级下拉列表框 /// ...
- ELK入门级介绍--打造实时日志查询系统
这几天一直在研究ElasticSearch,在网上看到一篇好的文章和大家分享. ELK平台介绍 在搜索ELK资料的时候,发现这篇文章比较好,于是摘抄一小段: 以下内容来自:http://baidu.b ...
- 打造实时数据集成平台——DataPipeline基于Kafka Connect的应用实践
导读:传统ETL方案让企业难以承受数据集成之重,基于Kafka Connect构建的新型实时数据集成平台被寄予厚望. 在4月21日的Kafka Beijing Meetup第四场活动上,DataPip ...
- 稍微成型点的用WEBSOCKET实现的实时日志LOG输出
难的是还是就地用JS显示出来相关的发布进度. 还好,花了一下午实现了. 可以移植到项目中去罗... websocket.py: import tornado.ioloop import tornado ...
- [PHP] php作为websocket的客户端实时读取推送日志文件
首先要使用composer来下载一个第三方扩展就可以实现php的websocket客户端,直接在当前目录生成下composer.json文件就可以了composer require textalk/w ...
- 10几行代码,用python打造实时截图识别OCR
你一定用过那种“OCR神器”,可以把图片中的文字提取出来,极大的提高工作效率. ! 今天,我们就来做一款实时截图识别的小工具.顾名思义,运行程序时,可以实时的把你截出来的图片中的文字识别出来. 下 ...
随机推荐
- [C#]WPF 分辨率的无关性的问题
什么是WPF的分辨率无关性? 首先得解什么是Dpi(Density independent pixels ,设备无关像素),百度百科的解释DPI是指每英寸的像素,对应界面显示即是屏幕上每英寸的像素. ...
- 【做题笔记】树形 dp
luoguP1122 最大子树和 Solve 设计状态 \(dp[i]\) 表示子树 \(i\) 的最大点权和,则有: 当 \(dp[son[i]] > 0\) 时,选以 \(son[i]\) ...
- Flutter状态管理-FlyingRedux
简介 Flying Redux 是一个基于Redux状态管理的组装式flutter应用框架. 它有四个特性: 函数式编程 可预测的状态 插拔式的组件化 支持null safety 和 flutter ...
- Flutter系列文章-Flutter进阶2
这一节我将再详细地为您介绍 Flutter 进阶主题,包括导航和路由.状态管理.异步处理.HTTP请求和Rest API,以及数据持久化.让我们逐个介绍这些主题. 1.导航和路由 在 Flutter ...
- 八 Appium常用方法介绍(转)
由于appium是扩展了Webdriver协议,所以可以使用webdriver提供的方法,比如在处理webview页面,完全可以使用webdriver中的方法.当然在原生应用中,也可以使用. 1.元素 ...
- 实现地图遮罩 leaflet
1 前言 在地图中加载的底图是瓦片服务(固定大小的规则矩形),底图的范围很大,铺满了整个div,但是我们的感兴趣的部门可能只是其中一部分,如何在整个屏幕中突出感兴趣的部分-- 地图遮罩(遮挡图像中不感 ...
- HTML5CSS3提高
1 HTML5新特性 1.1 概述 HTML5 的新增特性主要是针对于以前的不足,增加了一些新的标签.新的表单和新的表单属性等. 这些新特性都有兼容性问题,基本是 IE9+ 以上版本的浏览器才支持,如 ...
- 【技术积累】Docker部署笔记
服务器环境搭建 nacos镜像 使用宝塔Docker管理器直接拉起nacos环境并运行 注意:在同一台服务器中,nacos只对内网才能注册,图中172.17.0.2是内网地址,在多台服务器中需要跨ip ...
- 解决git出现fatal: detected dubious ownership in repository at XXXXX的错误
在window环境下,使用git命令时报错fatal: detected dubious ownership in repository at XXXXXX,图片如下 解决方法如下 添加一行代码 gi ...
- TCP的可靠性之道:确认重传和流量控制
TCP 全称为 Transmission Control Protocol(传输控制协议),是一种面向连接的.可靠的.基于字节流的传输层通信协议,其中可靠性是相对于其他传输协议的优势点.TCP 为了确 ...