Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >WebSocket新手入门指南

WebSocket新手入门指南

作者头像
蛮三刀酱
发布于 2022-01-05 07:50:02
发布于 2022-01-05 07:50:02
1.7K00
代码可运行
举报
运行总次数:0
代码可运行

文章目录

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

1 WebSocket 是什么

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
常见问题:

Q:WebSocket 能全双工,为何普通 HTTP 请求不行?(他们建立在 TCP 协议之上的,TCP 协议本就实现了全双工通信)
A:其实是 HTTP 的“请求-应答模式”限制了 TCP 协议本支持的全双工通信。

Q:WebSocket 和 Socket 的区别
A:Socket 不是协议,是应用层与 TCP/IP 通信的中间软件抽象层,是一组接口。而 WebSocket 是应用层协议。

Q:WebSocket 长连接和 HTTP 长连接的区别
AHTTP/1.1 默认开启了长连接(Connection:keep-alive),本质是 TCP 长连接,可在一次 TCP 连接中完成多个 HTTP 请求。
WebSocket 的长连接是真正的全双工,TCP 链路建立后,双方可以互发消息,无需再设置请求头,且双方都需要维持住这个连接。

关于 HTTP 长连接再多说几句,打开浏览器控制台 network,每个请求都会有个 Connection ID,这表示 TCP 连接的 id,会发现可能多个 HTTP 请求的 Connection ID 是一样的,这代表他们共用一个 TCP 连接。
另外 chrome 允许一个域名有 6TCP 连接并发,意味着同时发出的请求超过这个数字,只能排队了

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 长连接

事件

开发成本高

全双工;安全性高;节约带宽和资源

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 连接建立过程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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。
  • 配置示例:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;

    # 用于 WebSocket
    location /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 连接莫名其妙断了,后端日志发现有如下报错:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
com.tehang.callcenter.application.websocket.WebSocketConnection.onError
java.io.EOFException: null
 at 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://cloud.tencent.com/developer/article/1503133

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

https://cloud.tencent.com/developer/article/1502859

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

https://cloud.tencent.com/developer/article/1502853

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/12/14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
为什么有了http,还需要websocket,我懂了!
初次接触 websocket 的人,可能都会有这样的疑问:我们已经有了 http 协议,为什么还需要websocket协议?它带来了什么好处?
小许code
2023/11/21
1.2K1
为什么有了http,还需要websocket,我懂了!
干货 | 长连接/websocket/SSE等主流服务器推送技术比较
作者简介 本文由携程市场营销研发部武艺嫱和王宇星以及张子祥共同撰写,武艺嫱在市场营销研发部负责前端,王宇星和张子祥在市场营销研发部负责java后端。 最近做的某个项目有个需求,需要实时提醒client端有线上订单消息。所以保持客户端和服务器端的信息同步是关键要素,对此我们了解了可实现的方式。本文将介绍web常用的几种方式,希望给需要服务器端推送消息的同学在选型上有一点启发。 一、推送技术常用的集中实现的实现方式 1.1 短连接轮询: 前端用定时器,每间隔一段时间发送请求来获取数据是否更新,这种方式可兼容i
携程技术
2018/03/16
3.9K0
干货 | 长连接/websocket/SSE等主流服务器推送技术比较
动手实践,即时通讯WebSocket的代码实现
  随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。
java思维导图
2018/11/30
1K0
动手实践,即时通讯WebSocket的代码实现
IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2023/11/27
8170
IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket
新手入门:websocket
对于第1次听说WebSocket技术的人来说,两者有什么区别?websocket是仅仅将socket的概念移植到浏览器中的实现吗?
全栈程序员站长
2022/09/14
9190
新手入门:websocket
WebSocket协议 8 问
WebSocket是一种比较新的协议,它是伴随着html5规范而生的,虽然还比较年轻,但大多主流浏览器都已经支持。它使用方便、应用广泛,已经渗透到前后端开发的各种场景中。
xjjdog
2019/09/24
9400
WebSocket协议 8 问
WebSocket和Socket的区别,你真的知道吗?
应用场景: 网站上的即时通讯是很常见的,比如网页的QQ,聊天系统等。按照以往的技术能力通常是采用轮询、Comet技术解决。
Vincent-yuan
2021/12/20
10.3K0
WebSocket和Socket的区别,你真的知道吗?
WebSocket刨根问底(一)
年初的时候,写过两篇文章介绍在Spring Boot中如何使用WebSocket发送消息【在Spring Boot框架下使用WebSocket实现消息推送】【在Spring Boot框架下使用WebSocket实现聊天功能/http://blog.csdn.net/u012702547/article/details/53835453】,最近看到很多小伙伴对WebSocket的讨论还比较火热,so,打算写几篇文章来系统的介绍下websocket。OK,废话不多说,下面开始我们的正文。 为什么要有WebSo
江南一点雨
2018/04/02
1.1K0
WebSocket刨根问底(一)
3分钟使用 WebSocket 搭建属于自己的聊天室(WebSocket 原理、应用解析)
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2023/11/22
3.5K1
3分钟使用 WebSocket 搭建属于自己的聊天室(WebSocket 原理、应用解析)
websocket
拉的方式比较耗费资源,因为http是无状态且单向的通讯协议,后端无法主动xia向前端发送信息,一般拉为前端不间断的向服务端发送http请求,这种方式前端和后端都比较头疼。没有特殊需求的话,一般使用推的方式。HTML5开始提供websocket解决方式,基于TCP实现客户端与服务端全双工通信。websocket只使用了一个连接,避免了连接的多次建立;且只有连接初次建立比较复杂,后期通信成本较低。
wo.
2021/06/15
1.4K0
八问WebSocket协议:为你快速解答WebSocket热门疑问
WebSocket是一种比较新的协议,它是伴随着html5规范而生的,虽然还比较年轻,但大多主流浏览器都已经支持。它使用方面、应用广泛,已经渗透到前后端开发的各种场景中。
JackJiang
2019/04/25
1.3K0
websocket
短轮询(Polling)的实现思路就是 浏览器端 每隔几秒钟向 服务器端 发送http请求,服务端在收到请求后,不论是否有数据更新,都直接进行响应。 在服务端响应完成,就会关闭这个Tcp连接 ,如下图所示:
用户10106350
2022/10/28
2.7K0
JavaScript 服务器推送技术之 WebSocket
编者按:本文转载自 SHERlocked93 的掘金文章,跟着作者一起来学习一下吧
苏南
2020/12/16
1.6K0
JavaScript 服务器推送技术之 WebSocket
workerman的websocket的wss实例
Workerman不是重复造轮子,它不是一个MVC框架,而是一个更底层更通用的服务框架,你可以用它开发tcp代理、梯子代理、做游戏服务器、邮件服务器、ftp服务器、甚至开发一个php版本的redis、php版本的数据库、php版本的nginx、php版本的php-fpm等等。Workerman可以说是PHP领域的一次创新,让开发者彻底摆脱了PHP只能做WEB的束缚。
OwenZhang
2022/05/30
3.7K7
workerman的websocket的wss实例
什么是WebSocket协议?
随着科技发展,人们需求越来越多,生活的方方面面都离不开一些实时信息。比如:疫情期间在家协同办公、疫情监控目标人的实时运动轨迹、社交中的实时消息、多玩家互动游戏、每秒瞬息万变的股市基金报价、体育实况播放、音视频聊天、视频会议、在线教育等等,都可以借用WebSocket TCP链接可以让数据飞起来。下面就聊一下WebSocket协议。
没有故事的陈师傅
2022/04/05
7900
WebSocket 原理浅析与实现简单聊天
随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高,在 WebSocket 出现之前,大多数情况下是通过客户端发起轮询来拿到服务端实时更新的数据,因为 HTTP1.x 协议有一个缺陷就是通信只能由客户端发起,服务端没法主动给客户端推送。这种方式在对实时性要求比较高的场景下,比如即时通讯、即时报价等,显然会十分低效,体验也不好。为了解决这个问题,便出现了 WebSocket 协议,实现了客户端和服务端双向通信的能力。介绍 WebSocket 之前,还是让我们先了解下轮询实现推送的方式。
政采云前端团队
2019/12/20
1.1K0
WebSocket 原理浅析与实现简单聊天
网页端IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket
对Web端即时通讯技术熟悉的开发者来说,我们回顾网页端IM的底层通信技术,从短轮询、长轮询,到后来的SSE以及WebSocket,使用门槛越来越低(早期的长轮询Comet这类技术实际属于hack手段,使用门槛并不低),技术手段越来越先进,网页端即时通讯技术的体验也因此越来越好。
JackJiang
2021/05/25
1.7K0
轮询、长轮询、长连接、WebSocket
实现即时通讯常见的有四种方式,分别是:轮询、长轮询(comet)、长连接(SSE)、WebSocket。
十玖八柒
2022/08/01
7.5K0
轮询、长轮询、长连接、WebSocket
谈谈Websockt
它是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
张炳
2019/08/02
7610
websocket握手过程,和socket的区别
如果是写后端的,或者服务器的,肯定都知道socket是什么,套接字,其实就是对TCP和UDP协议封装的接口,相当于是一个库,提供很多函数接口API供我们使用。
opencode
2022/12/26
7310
websocket握手过程,和socket的区别
相关推荐
为什么有了http,还需要websocket,我懂了!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验