WebSocket笔记

WebSocket笔记,第1张

WebSocket笔记 一. 什么是WebSocket

WebSocket 是一种在单个TCP连接上进行全双工通信的协议。WebSocket 使得客户端服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接, 并进行双向数据传输。(维基百科)

WebSocket 是一种计算机网络应用层的协议,用来弥补http协议在持久通信能力上的不足。

WebSocket 的其他特点包括:

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

HTTP 协议有一个缺陷:通信只能由客户端发起,不具备服务器推送能力。
连续状态变化 http轮询,效率低,浪费资源。

相同点: 都是一样基于TCP的,都是可靠性传输协议。都是应用层协议。

联系: WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。

  1. WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息,而HTTP是单向的;
  2. WebSocket是需要浏览器和服务器握手进行建立连接的,而http是浏览器发起向服务器的连接。
WebSocket协议的原理

与http协议一样,WebSocket协议也需要通过已建立的TCP连接来传输数据。具体实现上是通过http协议建立通道,然后在此基础上用真正的WebSocket协议进行通信,所以WebSocket协议和http协议是有一定的交叉关系的。

http Request = Response

WebSocket握手

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket // 核心
Connection: Upgrade // 核心,告诉 Apache 、 Nginx 等服务器:注意啦,我发起的请求要用 WebSocket 协议
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== // 浏览器随机生成,base64 encode值
Sec-WebSocket-Protocol: chat, superchat // 用户定义的字符串,用来区分同 URL 下,不同的服务所需要的协议。
Sec-WebSocket-Version: 13 // 协议版本
Origin: http://example.com

返回

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= // 经过服务器确认,并且加密过后的 Sec-WebSocket-Key
Sec-WebSocket-Protocol: chat

WebSocket连接的过程是:
首先,客户端发起http请求,经过3次握手后,建立起TCP连接;http请求里存放WebSocket支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等;
然后,服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据;
最后,客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信。

优缺点
  • 优点:WebSocket协议一旦建议后,互相沟通所消耗的请求头是很小的
    服务器可以向客户端推送消息了
  • 缺点:少部分浏览器不支持,浏览器支持的程度与方式有区别(IE10)
应用场景
  • 即时聊天通信
  • 多玩家游戏
  • 在线协同编辑/编辑
  • 实时数据流的拉取与推送
  • 体育/游戏实况
  • 实时地图位置
  • 即时Web应用程序:即时Web应用程序使用一个Web套接字在客户端显示数据,这些数据由后端服务器连续发送。在WebSocket中,数据被连续推送/传输到已经打开的同一连接中,这就是为什么WebSocket更快并提高了应用程序性能的原因。 例如在交易网站或比特币交易中,这是最不稳定的事情,它用于显示价格波动,数据被后端服务器使用Web套接字通道连续推送到客户端。
  • 游戏应用程序:在游戏应用程序中,你可能会注意到,服务器会持续接收数据,而不会刷新用户界面。屏幕上的用户界面会自动刷新,而且不需要建立新的连接,因此在WebSocket游戏应用程序中非常有帮助。
  • 聊天应用程序:聊天应用程序仅使用WebSocket建立一次连接,便能在订阅户之间交换,发布和广播消息。它重复使用相同的WebSocket连接,用于发送和接收消息以及一对一的消息传输。
不能使用WebSocket的场景

如果我们需要通过网络传输的任何实时更新或连续数据流,则可以使用WebSocket。如果我们要获取旧数据,或者只想获取一次数据供应用程序使用,则应该使用HTTP协议,不需要很频繁或仅获取一次的数据可以通过简单的HTTP请求查询,因此在这种情况下最好不要使用WebSocket。
注意:如果仅加载一次数据,则RESTful Web服务足以从服务器获取数据。

WebSocket 的用法
var ws = new WebSocket("wss://echo.websocket.org");

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
  ws.close();
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
};      
断线重连 如何判断在线离线?

当客户端第一次发送请求至服务端时会携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果不存在就存入db或者缓存中,
第二次客户端定时再次发送请求依旧携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果存在就把上次的时间戳拿取出来,使用当前时间戳减去上次的时间,
得出的毫秒秒数判断是否大于指定的时间,若小于的话就是在线,否则就是离线;

如何解决断线问题

通过查阅资料了解到 nginx 代理的 websocket 转发,无消息连接会出现超时断开问题。网上资料提到解决方案两种,一种是修改nginx配置信息,第二种是websocket发送心跳包。

  1. 关闭
    ws.close();
  2. 主动发送消息
    ws.send("hello world");
参考资料
  • https://juejin.cn/post/7020964728386093093
  • https://www.ruanyifeng.com/blog/2017/05/websocket.html
  • https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5637460.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存