四十:如何从HTTP升级到WebSocket

在现代的Web应用中,随着实时通信需求的增加,传统的HTTP协议已无法满足高效、低延迟双向通信的需求。WebSocket协议应运而生,成为了一种解决方案,可以在客户端和服务器之间建立一个持久的双向通信通道。

本文将介绍如何从HTTP协议升级到WebSocket协议,包括WebSocket的握手过程、实现步骤以及需要注意的事项。

什么是WebSocket协议?

WebSocket是一种基于TCP协议的全双工通信协议,能够在客户端和服务器之间提供持久的、低延迟的通信通道。一旦建立连接,WebSocket可以支持实时的双向数据传输,而无需每次请求都重新建立连接。与HTTP协议不同,WebSocket更适合用于即时消息推送、在线游戏、实时股票行情等场景。

从HTTP升级到WebSocket的握手过程

WebSocket连接的建立首先依赖于一个HTTP协议的"握手"过程。这个过程涉及客户端与服务器之间交换一些特定的HTTP头部信息,一旦握手成功,协议便从HTTP升级到WebSocket,之后便可以开始双向数据传输。

1. 客户端发起WebSocket请求

客户端通过发送一个特殊的HTTP请求来请求升级到WebSocket协议。这个请求是通过HTTP协议发送的,但它包含了一些额外的头部信息,告诉服务器客户端希望将连接升级为WebSocket。

请求的关键部分是:

  • Upgrade: 告诉服务器客户端希望进行协议升级。
  • Connection: 表示当前连接将被升级。
  • Sec-WebSocket-Key: 这个随机生成的字符串是WebSocket协议的一部分,用于在握手时验证。
  • Sec-WebSocket-Version: 指定客户端支持的WebSocket协议版本,当前最新版本是13。

客户端请求的例子:

复制代码
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

2. 服务器响应WebSocket请求

服务器收到客户端的升级请求后,会验证请求的合法性,并通过返回特定的HTTP响应来同意进行协议升级。服务器返回的响应头部信息将确认升级。

响应的关键部分是:

  • Upgrade: 指示服务器同意进行协议升级。
  • Connection: 确保连接被正确地升级。
  • Sec-WebSocket-Accept : 这个值是对客户端Sec-WebSocket-Key进行处理后的结果,主要用于防止请求伪造。

服务器响应的例子:

复制代码
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: dGhlIHNhbXBsZSBub25jZQ==

3. 升级成功,WebSocket连接建立

当客户端收到服务器的101 Switching Protocols响应时,表明WebSocket连接已经成功建立。此时,客户端和服务器之间的通信已经不再使用HTTP协议,而是转换为WebSocket协议,可以进行实时、双向的数据传输。

实现WebSocket连接的步骤

从HTTP协议升级到WebSocket协议的过程在Web开发中非常常见,特别是在需要实时交互的应用场景下。以下是实现这一过程的基本步骤:

1. 客户端实现

在客户端,浏览器支持WebSocket API,因此可以通过JavaScript代码轻松地发起WebSocket连接。示例代码如下:

复制代码
const socket = new WebSocket('ws://example.com/chat');

// 连接成功时的回调函数
socket.onopen = function(event) {
  console.log('WebSocket connection established');
  socket.send('Hello, server!');
};

// 接收到服务器消息时的回调函数
socket.onmessage = function(event) {
  console.log('Received message from server: ' + event.data);
};

// 连接关闭时的回调函数
socket.onclose = function(event) {
  console.log('WebSocket connection closed');
};

// 发生错误时的回调函数
socket.onerror = function(error) {
  console.log('WebSocket error: ' + error);
};

2. 服务器实现

WebSocket协议本身并没有定义具体的服务器实现方式,开发者可以根据自己使用的技术栈选择不同的WebSocket库或框架。以下是使用Node.js和ws库实现WebSocket服务器的一个例子:

首先,安装ws库:

复制代码
npm install ws

然后,在服务器端实现WebSocket连接的处理:

复制代码
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
  console.log('Client connected');
  
  // 监听客户端发送的消息
  ws.on('message', (message) => {
    console.log('Received: ' + message);
  });
  
  // 向客户端发送消息
  ws.send('Hello, client!');
});

3. 确保安全性

WebSocket协议本身并不提供加密,因此对于需要保护数据传输的应用,应当使用WSS(WebSocket Secure)协议,即通过TLS/SSL加密的WebSocket。使用wss://而不是ws://来创建安全的WebSocket连接:

复制代码
const socket = new WebSocket('wss://example.com/chat');

注意事项

  • 协议版本: WebSocket协议的版本可能会随着规范的更新而变化。客户端和服务器必须支持相同的版本才能成功建立连接。当前版本是13,这是大多数浏览器和WebSocket库所支持的版本。
  • 防止滥用: 由于WebSocket连接是持久的,恶意用户可能会滥用这个特性。因此,确保WebSocket连接的安全性非常重要,例如使用身份验证、授权机制,以及限制连接的频率等。
  • 跨域问题: 默认情况下,WebSocket允许跨域通信,但也需要特别注意安全策略,避免未经授权的跨域连接。
  • 服务器资源: WebSocket连接一旦建立,直到连接关闭之前都处于开放状态。因此,服务器需要能够处理大量并发连接,并且要合理地管理资源。

总结

从HTTP协议升级到WebSocket协议是实现实时通信的关键步骤。通过握手过程,客户端和服务器能够顺利转换协议,建立持久的、双向的通信通道,进一步实现低延迟、实时的数据交换。实现这一过程非常简单,浏览器原生支持WebSocket API,服务器端可以通过多种框架和库进行支持。

无论是在即时消息、在线游戏还是实时数据推送等应用场景中,WebSocket都提供了一个高效的解决方案。随着互联网应用对实时性要求的不断提升,WebSocket的应用前景将更加广泛。

目录:

一:浏览器发起 HTTP 请求的典型场景_浏览器如何发送用户名密码的请求-CSDN博客

二:基于ABNF语义定义的HTTP消息格式-CSDN博客

三:网络为什么要分层:OSI模型与TCP/IP模型-CSDN博客

四:HTTP的诞生:它解决了哪些网络通信难题?-CSDN博客

五:评估Web架构的七大关键属性-CSDN博客

六:从五种架构风格推导出HTTP的REST架构-CSDN博客

七:如何用Chrome的Network面板分析HTTP报文-CSDN博客

八:URI的基本格式及其与URL的区别-CSDN博客

九:为什么要对URI进行编码?-CSDN博客

十:详解HTTP的请求行-CSDN博客

十一:HTTP 状态码详解:解读每一个响应背后的意义-CSDN博客

十二:HTTP错误响应码:理解与应对-CSDN博客

十三:如何管理跨代理服务器的长短连接?-CSDN博客

十四:HTTP消息在服务器端的路由-CSDN博客

十五:代理服务器转发消息时的相关头部-CSDN博客

十六:请求与响应的上下文-CSDN博客

十七:Web内容协商与资源表述-CSDN博客

十八:HTTP包体的传输方式(1):定长包体-CSDN博客

十九:HTTP包体的传输方式(2):不定长包体-CSDN博客

二十:HTML Form表单提交时的协议格式-CSDN博客

二十一:断点续传与多线程下载是如何做到的?-CSDN博客

二十二:Cookie的格式与约束-CSDN博客

二十三:Session及第三方Cookie的工作原理-CSDN博客

二十四:浏览器为什么要有同源策略?-CSDN博客

二十五:如何"合法"地跨域访问?-CSDN博客

二十六:Web条件请求的作用-CSDN博客

二十七:Web缓存的工作原理-CSDN博客

二十八:Web缓存新鲜度的四种计算方式-CSDN博客

二十九:复杂的Cache-Control头部解析-CSDN博客

三十:在 Web 中什么样的响应才会被缓存?-CSDN博客

三十一:HTTP多种重定向跳转方式的差异-CSDN博客

三十二:HTTP 协议的基本认证-CSDN博客

三十三:Wireshark的基本用法-CSDN博客

三十四:如何通过DNS协议解析域名?-CSDN博客

三十五:Wireshark的捕获过滤器-CSDN博客

三十六:Wireshark的显示过滤器-CSDN博客

三十七:WebSocket解决什么问题?-CSDN博客

三十八:WebSocket的约束-CSDN博客

三十九:WebSocket协议:实时通信的未来-CSDN博客

相关推荐
安卓开发者15 小时前
鸿蒙NEXT网络通信实战:使用HTTP协议进行网络请求
网络·http·harmonyos
夕泠爱吃糖16 小时前
TCP三次握手四次挥手
网络·网络协议·tcp/ip
TeleostNaCl17 小时前
如何在 Windows 上使用命令设置网卡的静态 IP 地址
网络·windows·经验分享·网络协议·tcp/ip·ip
XUE-521131418 小时前
组播实验-IGMP、IGMP Snooping及PIM-DM协议
运维·网络·网络协议·智能路由器
liulilittle19 小时前
OPENPPP2 静态隧道链路迁移平滑(UDP/IP)
开发语言·网络·c++·网络协议·tcp/ip·udp·通信
xxtzaaa20 小时前
抖音私密账号显示IP属地吗?能更改IP么?
网络·网络协议·tcp/ip
未来之窗软件服务1 天前
操作系统应用开发(二十五)RustDesk 502错误—东方仙盟筑基期
网络协议·远程桌面·仙盟创梦ide·东方仙盟·rustdek
眠りたいです1 天前
基于脚手架微服务的视频点播系统-脚手架开发部分-jsoncpp,protobuf,Cpp-httplib与WebSocketpp中间件介绍与使用
c++·websocket·微服务·中间件·json·protobuf·cpp-httplib
苜蓿草茸茸1 天前
HTTP 协议详解
网络协议·http
Apifox.1 天前
Apifox 9 月更新| AI 生成接口测试用例、在线文档调试能力全面升级、内置更多 HTTP 状态码、支持将目录转换为模块
前端·人工智能·后端·http·ai·测试用例·postman