文章目录

  • 介绍 WebSocket 的原理,了解原理后,用起来更放心大胆;
  • 类似技术对比,搞清楚自己的业务场景是不是需要使用 WebSocket;
  • 使用过程中的经验分享,让你少走一些弯路;

1 WebSocket 是什么

WebSocket 是 HTML5 新增的在单个 TCP 连接上进行全双工通讯(不受限的双向通信)的协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

全双工(Full Duplex)的通讯传输允许数据在两个方向上同时传输,相当于两个单工通信方式的结合。发送和接收分别由两根不同的传输线传送,通信双方既是发送器也是接收器。

Websocket 使用和 HTTP 相同的 TCP 端口,可以绕过大多数防火墙的限制。默认情况下,Websocket 协议使用 80 端口;运行在 TLS 上则使用 443 端口。

常见问题:Q:WebSocket 能全双工,为何普通 HTTP 请求不行?(他们建立在 TCP 协议之上的,TCP 协议本就实现了全双工通信)
A:其实是 HTTP 的“请求-应答模式”限制了 TCP 协议本支持的全双工通信。Q:WebSocket 和 Socket 的区别
A:Socket 不是协议,是应用层与 TCP/IP 通信的中间软件抽象层,是一组接口。而 WebSocket 是应用层协议。Q:WebSocket 长连接和 HTTP 长连接的区别
A:HTTP/1.1 默认开启了长连接(Connection:keep-alive),本质是 TCP 长连接,可在一次 TCP 连接中完成多个 HTTP 请求。
WebSocket 的长连接是真正的全双工,TCP 链路建立后,双方可以互发消息,无需再设置请求头,且双方都需要维持住这个连接。关于 HTTP 长连接再多说几句,打开浏览器控制台 network,每个请求都会有个 Connection ID,这表示 TCP 连接的 id,会发现可能多个 HTTP 请求的 Connection ID 是一样的,这代表他们共用一个 TCP 连接。
另外 chrome 允许一个域名有 6 个 TCP 连接并发,意味着同时发出的请求超过这个数字,只能排队了

2 为什么要用 WebSocket

2.1 需求描述、应用场景

  • 需求:服务端数据更新,需要通知到客户端。
  • 应用场景:聊天软件、订阅、游戏、协同工作(比如文本编辑)、直播、股票基金、基于位置的应用等。

2.2 常用解决方案对比

WebSocket 能解决上述需求,除此之外,常用的解决方案还有:轮询、长轮询。另外 html5 还提供了 Server-Sent Event。

  • 轮询:客户端定时向服务端发送 http 请求,服务端收到请求后立即返回响应信息并关闭连接;
  • 长轮询:为了解决轮询无效请求过多的问题,长轮询进行了优化,服务端收到请求后先阻塞,必要时再返回数据并关闭连接,客户端处理完响应信息后才再向服务端发送新的请求;
  • Server-Sent Event:html5 提供的,借用了长轮询的思想,但不再每个连接只收发一个消息,将文本数据换成流以实现重复在一个连接上收发消息;
常用方案 通讯方式 触发方式 缺点 优点
轮询 http 轮询 服务端不能主动推送;消息不及时;浪费带宽 实现容易
长轮询 http 轮询 服务端仍不能主动推送;占用 web 连接 实现较容易
Server-Sent Event http 事件 兼容性问题(不支持 ie); 占用 web 连接;只能服务端向客户端推 实现较容易;自动重连
WebSocket tcp 长连接 事件 开发成本高 全双工;安全性高;节约带宽和资源
  • Server-Sent Event 一个用于微信支付的案例:https://www.jianshu.com/p/9a0e802b2297
SSE suffers from a limitation to the maximum number of open connections, which can be specially painful when opening various tabs as the limit is per browser and set to a very low number (6). The issue has been marked as "Won't fix" in Chrome and Firefox
  • 长轮询和 SSE 会占用浏览器有限的连接数(chrome 有 6 个),看起来很致命啊

另外 HTTP/2 提供了服务器推送(Server Push)的功能,千万别和上面几个东西搞混了,完全不是一回事。服务器指的是 web 服务器,推送的对象是浏览器要加载的资源,是用于提升首屏加载速度的技术,需要在 web 服务器(比如 nginx)中开启相关配置。可以参考这篇:https://www.cnblogs.com/wetest/p/8040202.html

3 WebSocket 连接建立过程

WebSocket并不是全新的协议,而是利用了HTTP协议来建立连接。我们来看看WebSocket连接是如何创建的。

3.1 浏览器发起一个 http 请求建立连接

请求地址以ws://开头,请求头Upgrade: websocketConnection: Upgrade表示这个连接将要被转换为 WebSocket 连接。

  • 1.1 建立 TCP 连接
  • 1.2 浏览器发送 HTTP 请求,并携带协议升级的头信息,进行协议升级前的握手

3.2 服务器响应请求

响应头HTTP/1.1 101 Switching ProtocolsUpgrade: websocket表示本次连接的 HTTP 协议即将被更改(代码 101),改为指定的 WebSocket 协议。

  • 2.1 响应 HTTP 握手,返回 code 101
  • 2.2 双方可以通过这个连接自由的传信息,连接会持续存在,server 和 client 都可单方面断开连接

4 使用需知 & 实用指南

4.1 正确使用 ws 和 wss

  • WebSocket 的协议标识符是ws,如果在 TLS 协议上,标识符是wss,类似于 https
  • https 下必须使用 wss 作为安全链接

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

4.2 使用 Nginx 代理 WebSocket 请求

  • Nginx 从 1.3 开始就支持 WebSocket 了,并且可以为 WebSocket 应用程序做反向代理和负载均衡。官方文档:http://nginx.org/en/docs/http/websocket.html
  • 当客户端发过来一个协议升级的 http 请求时,Nginx 默认是不知道的,需要配置proxy_set_header Upgrade $http_upgradeproxy_set_header Connection "Upgrade", 配置后,当 Nginx 代理服务器拦截到客户端发来的 Upgrade 请求时,会使用 101(交换协议)返回响应,在客户端和代理服务器、后端服务器之间建立隧道来支持 WebSocket。
  • 配置示例:
server {listen       80;server_name dev-staff-api-gateway.teyixing.com;rewrite ^(.*)$ https://${server_name}$1 permanent;
}
server {server_name dev-staff-api-gateway.teyixing.com;listen 443 http2 ssl;ssl_certificate conf.d/cert/teyixing.com.pem;ssl_certificate_key conf.d/cert/teyixing.com.key;ssl_session_timeout 5m;ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_prefer_server_ciphers on;# 用于 WebSocketlocation /v1/webSocket {proxy_pass http://dev-staff-api-gateway/v1/webSocket; # http://call-center/v1/webSocket;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade";}# 拦截普通 http 请求location / {proxy_pass http://dev-staff-api-gateway;}
}

4.3 如何解决 nginx 掐断 WebSocket 连接的问题

4.3.1 问题简述

有时候会发现 WebSocket 连接莫名其妙断了,后端日志发现有如下报错:

com.tehang.callcenter.application.websocket.WebSocketConnection.onError
java.io.EOFException: nullat org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1208)at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1142)at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:72)at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171)at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151)at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148)at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54)at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.base/java.lang.Thread.run(Thread.java:834)

4.3.2 原因

  • nginx 配置项 proxy_read_timeout 的默认值为 60s,表示等待服务器响应的时间。也就是说,当 WebSocket 使用 nginx 转发时,如 60s 内没有通讯,nginx 便会掐断连接。

4.3.3 解决方案

  • nginx proxy_read_timeout 设置为不超时
  • 前端发起心跳检测
  • 前端在 WebSocket 生命周期方法 onError 中调用 reconnect

进阶教程

[WebSocket入门]手把手搭建WebSocket多人在线聊天室(SpringBoot+WebSocket)

https://blog.csdn.net/qqxx6661/article/details/98883166

[WebSocket]第二章:WebSocket集群分布式改造——实现多人在线聊天室

https://blog.csdn.net/qqxx6661/article/details/100064741

[WebSocket]使用WebSocket实现实时多人答题对战游戏

https://blog.csdn.net/qqxx6661/article/details/100597812

WebSocket新手入门指南相关推荐

  1. mac 删除分区 command r 选择网络_Mac使用必看基础篇,Mac快捷键大全,mac新手入门指南...

    你是Mac新手吗?你对使用Mac电脑有疑问吗?你还不知道mac有哪些快捷键吗?别着急,来看看小编给大家准备的Mac使用必看基础篇--Mac快捷键大全,对于新手用户很有帮助哦!! 一.开机相关命令快捷键 ...

  2. Neo4j 新手入门指南

    Neo4j 新手入门指南 前言: 前段时间在公司实习有用到图数据库做一个小项目,就想着记录一下当时找到的比较有用的资料. 纯属入门学习啦,新手当作一个大纲来学习也可以! 感谢关注! 所有链接均在文章结 ...

  3. python pip-什么是pip?Python新手入门指南

    什么是 pip ?pip 是 Python 中的标准库管理器.它允许你安装和管理不属于 Python标准库 的其它软件包.本教程就是为 Python 新手介绍 pip. 通过本教程,你将学到: 1. ...

  4. 蓝桥云课之新手入门指南

    这是蓝桥云课学习人数最多的课程: 新手入门指南之玩转蓝桥云课 460896 人学过 27739 次评价 作者: 云课管理员 难度: 初级 综合评分: 9.4 复习一遍,里面共有3中课程模式: 第一种, ...

  5. rust油桶用什么打_腐蚀rust新手入门指南 游戏新萌拿好不谢!

    川北在线核心提示:原标题:腐蚀rust新手入门指南 游戏新萌拿好不谢! 如何开始游戏? 巴拉巴拉那么多现在开始步入正轨吧! 点击find game 就进入了服务器列表,在这里你可以加入官方的服务器(热 ...

  6. 新手入门指南之玩转蓝桥云课

    新手入门指南之玩转蓝桥云课 文档1  你好,蓝桥云课 实验1 Linux 桌面环境使用指南 本实验采用的就是图形界面的 Linux 桌面环境.图形界面使用的是非常优秀的 Ubuntu Linux 操作 ...

  7. Apache Kylin新手入门指南

    Apache Kylin新手入门指南 文章目录 Apache Kylin新手入门指南 1 Apache Kylin是什么 2 为什么使用Apache Kylin 3 Apache Kylin的易用性如 ...

  8. 从零开始学黑客:网络黑客新手入门指南(转)

    从零开始学黑客:网络黑客新手入门指南(转) (一)系统基本知识 1.a.什么是IP:要是真的想说清楚什么是IP,那是一项很繁重的工作.简单的来说,IP就是所有Internet或是局域网上的主机的身份证 ...

  9. 阿里云机器学习怎么玩?这本新手入门指南揭秘了!

    想知道我是怎样免费在阿里云上玩机器学习的吗? 不慌,这就告诉你答案~ 它来了--阿里云向个人免费开放云端深度学习开发环境DSW(DataScienceWorkshop),还有免费GPU资源可以使用,实 ...

最新文章

  1. css float 的使用
  2. python爬虫吧-Python爬虫案例集合
  3. cognos10 安装部署
  4. asp.net上传图片自动生成缩略图功能代码
  5. 发布 CodeAuto 代码生成器 2.1.0.461 中英文双语版
  6. android studio 自动实现方法,Android Studio怎么自动实现所有的接口函数
  7. 微星主板黑苹果_记一次黑苹果PC装机全过程
  8. 学机器人编程还是计算机编程,为什么要学习机器人编程课程
  9. 【Excel】设置自定义单元格格式
  10. 穷爸爸与富爸爸读后感 (2)
  11. 常见文件扩展名及简要说明
  12. 路由来源、优先级和度量值
  13. 制造业大量招程序员,是拧螺丝吗?
  14. Mysql主从复制的三种同步方式和半同步复制配置
  15. 全息投影技术未来的发展趋势
  16. 探索者 STM32F407 与 HC05 蓝牙模块相连
  17. 微盟PK有赞,谁更胜一筹?
  18. 蓝桥试题 算法训练 区间k大数查询 JAVA
  19. or和union all
  20. 【Java】生产者消费者模式的三种实现

热门文章

  1. 压着谷歌打!ChatGPT提前上岗微软搜索,现在就能用,纳德拉:竞赛今天才开始...
  2. 2023年春《移动计算技术》:基于Python的【道路交通流仿真】示例:直行道路/环形路口/十字交叉路口(含红绿灯) 交通流仿真
  3. Uncaught TypeError: VueRouter is not a constructor at 路由.html:39:18
  4. 蓝本蓝科技:做好社群活动的8个环节,有效提升社群活跃度​
  5. 淘宝API接口:item_search_shop - 获得店铺的所有商品
  6. 【Oracle】数据发散分析
  7. 【python爬虫自学笔记】-----爬取网易云歌单中歌曲歌词
  8. l2tp lns设置chap和pap
  9. python画苹果图案_如何用python画苹果?
  10. 组织过程资产的内容和构成