草庐IT

WebSocket的那些事(1-概念篇)

凌波漫步& 2025-07-08 原文

目录

一、什么是Websocket

根据 RFC 6455 标准,Websocket协议提供了一种标准化的方式在客户端和服务端之间通过TCP连接建立全双工、双向通信渠道。它是一种不同于HTTP的TCP协议,但是被设计为在HTTP基础上运行。

Websocket交互始于HTTP请求,该请求会通过HTTP Upgrade请求头去升级请求,进而切换到Websocket协议。请求报文如下:

GET /spring-websocket-portfolio/portfolio HTTP/1.1
Host: localhost:8080
Upgrade: websocket 
Connection: Upgrade 
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080

我们可以看到在该请求报文中有两个特殊的请求头,一个是Upgrade请求头,代表升级为websocket协议。还有一个是Connection请求头,代表升级连接。

正常的HTTP响应报文如果正常返回,响应码是200,请求升级为websocket协议的响应报文如下:

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp

我们可以看到该响应报文中状态行返回的响应码是101,后面还附带了Switching Protocols切换协议关键字。

在成功握手后,底层HTTP升级请求TCP套接字会在客户端和服务端之间保持开放,从而继续发送和接收消息。

备注:关于Websockets如何工作的完整文档可以参考 RFC 6455


二、WebSocket部分header介绍

我们可以看到请求和响应报文中有一些特殊的websocket头部信息,这里简单的介绍一下:

  • Sec-WebSocket-Key:用于客户端与服务端初次握手唯一标识,Base64编码字符串。
  • Sec-WebSocket-Accept:初次握手服务端返回的唯一标识,也是Base64编码字符串,用来证明来自客户端的握手请求已经收到了,该响应头的值为:SHA-1(“Sec-WebSocket-Key” + “GUID”),然后再经过Base64编码。

备注:这里的GUID为固定值 258EAFA5-E914-47DA-95CA-C5AB0DC85B11

  • Sec-WebSocket-Protocol:WebSocket子协议,比如可以是STOMP协议。
  • Sec-WebSocket-Version:WebSocket协议版本号,值必须为13。

三、HTTP VS WebSocket

虽然WebSocket被设计成和HTTP协议兼容,但是两种协议有不同的架构和应用编程模型。

在HTTP和REST中,应用被模型化为许多URL,客户端和应用交互需要访问这些URL,服务端对请求进行路由并交给合适的处理器,处理器会基于HTTP URL、方法和头部进行处理。

WebSocket和HTTP相反,通常只有一个URL用于初始链接,后面所有应用消息都会在相同的TCP连接上传输,这是一种完全不同的异步、事件驱动的消息。

WebSocket也是一种低级的传输协议,不像HTTP,它并没有规定消息内容的语义,也就意味着客户端和服务端之间如果没有对消息语义达成一致,是没办法路由和处理消息的。

WebSocket客户端和服务端之间可以协商使用更高级消息协议,比如STOMP,可以通过HTTP握手请求的请求头Sec-WebSocket-Protocol指定。


四、什么时候使用WebSockets

WebSockets可以让Web页面动态化和可交互,然而,在很多场景下,AJAXHTTP Streaming或者长轮询也能提供简单、有效的解决方案。

例如,新闻、邮件和社会实事需要动态更新,每几分钟更新一次就好。而协作类、游戏和金融类APP需要更加的实时。

延时也不是决定性因素,如果消息体量比较小,HTTP Streaming或者长轮询也能解决,而像低延时、高频次和大消息体量的场景,WebSocket更适合。


五、关于SockJS和STOMP

SockJSSTOMP 都是用于 Web 应用程序与消息代理进行通信的技术,但它们解决的问题不同。

SockJS 是一个 JavaScript 库,它提供了一种在 Web 浏览器和 Web 服务器之间建立 WebSocket 连接的跨浏览器解决方案。

SockJS 旨在解决 WebSocket 不受支持或无法使用的情况下,使用轮询和其他技术建立实时双向通信的问题。SockJS 库支持多种传输方式,包括 WebSocket、XHR 流、XHR 短轮询等,从而保证了最大的兼容性和可靠性。

STOMP(Simple Text Oriented Messaging Protocol)是一种基于文本的简单消息协议,它提供了一种可互操作性的机制,用于跨语言和平台之间的实时消息传递。

STOMP 协议定义了一组命令和消息格式,用于在客户端和服务器之间进行消息传递,它与特定的消息代理无关,因此可以使用 STOMP 协议与多个消息代理进行通信。STOMP 支持订阅/发布模式和点对点模式,可以用于实现诸如聊天室、通知系统和实时数据更新等应用程序。

通常情况下,使用 SockJSSTOMP结合使用可以获得最佳的性能和可靠性。

SockJS 提供了一种建立 WebSocket 连接的可靠跨浏览器解决方案,而 STOMP 提供了一种在 WebSocket 连接上实现实时消息传递的标准化协议。

在使用 SockJSSTOMP 的组合时,可以使用 SockJS 建立 WebSocket 连接,然后使用 STOMP 协议在 WebSocket 连接上进行消息传递,从而获得最佳的性能和可靠性。

有关WebSocket的那些事(1-概念篇)的更多相关文章

  1. ruby - Faye WebSocket,关闭处理程序被触发后重新连接到套接字 - 2

    我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d

  2. C/C++好用的websocket库 - 2

    IntrductionLibwebsocketsisasimple-to-use,MIT-license,pureClibraryprovidingclientandserverforhttp/1,http/2,websockets,MQTTandotherprotocolsinasecurity-minded,lightweight,configurable,scalableandflexibleway.It’seasytobuildandcross-buildviacmakeandissuitablefortasksfromembeddedRTOSthroughmasscloudservi

  3. ruby-on-rails - Websocket-rails 不适用于 Nginx 和 Unicorn 的生产环境 - 2

    我有带有gemwebsocket-rails0.7的Rails3.2应用程序。在开发机上,一切正常在生产环境中,我使用Nginx/1.6作为代理服务器,Unicorn作为http服务器。Thin用于独立模式(在https://github.com/websocket-rails/websocket-rails/wiki/Standalone-Server-Mode之后)。nginx配置:location/websocket{proxy_passhttp://localhost:3001/websocket;proxy_http_version1.1;proxy_set_headerUp

  4. WebSocket的那些事(1-概念篇) - 2

    目录一、什么是Websocket二、WebSocket部分header介绍三、HTTPVSWebSocket四、什么时候使用WebSockets五、关于SockJS和STOMP一、什么是Websocket根据RFC6455标准,Websocket协议提供了一种标准化的方式在客户端和服务端之间通过TCP连接建立全双工、双向通信渠道。它是一种不同于HTTP的TCP协议,但是被设计为在HTTP基础上运行。Websocket交互始于HTTP请求,该请求会通过HTTPUpgrade请求头去升级请求,进而切换到Websocket协议。请求报文如下:GET/spring-websocket-portfoli

  5. 半个月狂飙1000亿,ChatGPT概念股凭什么? - 2

    ChatGPT掀起了AI股历史上最疯狂的一轮市值狂飙。自春节后至今,ChatGPT概念股开始了暴走模式,短短半月时间,海天瑞声、开普云等ChatGPT概念股市值累计增加了近1400亿。如此的爆炸效应,得益于ChatGPT所展现出商业化落地的巨大潜力。要知道,在此之前,无论是十年AI投入超千亿的百度,还是困在硬件化里的AI四小龙,都在重复着AI商业化难落地的故事。ChatGPT的出现,让AI从生产力的赋能者直接成为一种创造生产力的工具。随着订阅模式的推出,ChatGPT已经成为第一个以AI技术为核心直接变现的消费者应用。本文持有以下核心观点:1、ChatGPT是AI技术迭代的受益者。过去受限技术

  6. “网安三人行”盘点:软件供应链安全的那些事儿 - 2

    2022年伊始,默安科技联合数世咨询举办以“软件供应链安全的时与势”为主题的访谈活动,由数世咨询创始人李少鹏主持,邀请贝壳安全研发负责人李文鹏、北京邮电大学副教授张文博、默安科技副总裁沈锡镛三位行业大咖做客网安小酒馆,从产业、企业、学术的不同维度,共同探讨软件供应链安全建设的新思路,为业界呈现了一场开年网安盛宴。随着全球软件供应链安全事件频发,软件供应链安全逐渐成为业界关注焦点,也成为影响国家重要信息系统安全与关键信息基础设施安全的重要因素,以及网络安全保障体系和能力建设的重要环节。嘉宾们围绕软件供应链安全发展的主要驱动力、关基行业中的实施现状和落地难点、产学研成果转化、软件供应链安全的重要性

  7. ruby-on-rails - 如何使用 Rails/websocket-rails(独立)调试 'Invalid frame header' Websocket 问题 - 2

    我开始使用websocket-rails,试图将旧的通知轮询系统(在Ruby2.1/Rails4.0上)转换为更现代的WS系统。我在独立模式下使用WebsocketRails,这是我的配置,基本上是默认配置:WebsocketRails.setupdo|config|config.standalone=trueend我还设置了一个在默认端口上运行的新Redis-这里似乎没有通信问题。在客户端,我添加了websocket-rails的JS,并在尝试打开连接和订阅channel时使用:@dispatcher=newWebSocketRails"localhost:3001/websocke

  8. ruby - 在 Ruby 的正则表达式中,前瞻和后视概念如何支持这种零宽度断言概念? - 2

    我刚刚经历了这个概念Zero-WidthAssertions从文档中。我想到了一些快速的问题-为什么这样的名字Zero-WidthAssertions?Look-ahead怎么了和look-behind概念支持这样的Zero-WidthAssertions概念?什么这样的?,,=s,-4个符号在模式内指示?你能帮我集中精力了解实际发生的事情我还尝试了一些小代码来理解逻辑,但对它们的输出没有那么自信:irb(main):001:0>"foresight".sub(/(?!s)ight/,'ee')=>"foresee"irb(main):002:0>"foresight".sub(/(?

  9. 涡旋光束基本概念介绍 - 2

    涡旋光束及其MATLAB实现前言涡旋光束的基本概念常见的涡旋涡旋光束涡旋光束的产生方法前言笔者新开一块专栏,专门用于讨论整理总结涡旋光束的相关内容,从基本的概念出发,推导相关的公式,并结合MATLAB进行相关的仿真,不清楚这个专栏会更新多少期,我会分享部分的代码,全部的代码有需要的话可以私聊我。当然大家对这个专栏感兴趣的话,欢迎积极交流。涡旋光束的基本概念​涡旋光束(vortexbeam)是指携带光学涡旋,具有exp(imϕ)exp(im\phi)exp(imϕ)相位分布的光束,其中mmm表示相位拓扑电荷数,ϕ\phiϕ是柱坐标下的方位角。之前的分享中笔者已经说明了部分的激光光束的表达式,想要

  10. ruby-on-rails - ActionCable - 无法在生产环境中升级到 WebSocket - 2

    ActionCable在生产中不起作用。在开发中运行良好,但在生产中运行不佳。在Ubuntu14.04上使用Puma运行Nginx。我已经检查过redis-server已启动并正在运行。Rails-v5.0.0.1production.log:INFO--:StartedGET"/cable/"[non-WebSocket]for178.213.184.193at2016-11-2514:55:39+0100ERROR--:FailedtoupgradetoWebSocket(REQUEST_METHOD:GET,HTTP_CONNECTION:close,HTTP_UPGRADE:)

随机推荐