您当前的位置:首页 > 电脑百科 > 网络技术 > 网络知识

即时通讯协议选型:WebSocket协议

时间:2022-10-20 17:05:36  来源:今日头条  作者:音视频开发老舅

日常开发中我们出于保证连接的稳定性的目的,将应用拆分成了「主进程」和「通讯进程」,并为二者定义了相互通信的接口。

即便如此,我们也只是实现了客户端一侧的进程间通信,而要实现与完整聊天系统中另一端的角色——服务端的通信,则需依靠「网络通信协议」来协助完成

在此我们选用的是WebSocket协议。

什么是WebSocket?

WebSocket一词,从词面上可以拆解为 Web & Socket 两个单词,Socket我们并不陌生,其是对处于网络中不同主机上的应用进程之间进行双向通信的端点的抽象,是应用程序通过网络协议进行通信的接口,一个Socket对应着通信的一端,由IP地址和端口组合而成。需要注意的是,Socket并不是具体的一种协议,而是一个逻辑上的概念。

那么WebSocket和Socket之间存在着什么联系呢,是否可以理解为是Socket概念在Web环境的移植呢?为了解答这个疑惑,我们先来回顾一下,在JAVA平台上进行Socket编程的流程:

 

  1. 服务端创建ServerSocket实例并绑定本地端口进行监听
  2. 客户端创建Socket实例并指定要连接的服务端的IP地址和端口
  3. 客户端发起连接请求,服务端成功接受之后,双方就建立了一个端对端的TCP连接,在该连接上可以双向通信。而后服务端继续处于监听状态,接受其他客户端的连接请求。

 

上述流程还可以简化为:

 

  1. 服务端监听
  2. 客户端请求
  3. 连接确认

 

与之类似,WebSocket服务端与客户端之间的通信过程可以描述为:

 

  • 服务端创建包含有效主机与端口的WebSocket实例,随后启动并等待客户端连接
  • 客户端创建WebSocket实例,并为该实例提供一个URL,该URL代表希望连接的服务器端
  • 客户端通过HTTP请求握手建立连接之后,后面就使用刚才发起HTTP请求的TCP连接进行双向通信。

 


 

WebSocket协议最初是html5规范的一部分,但后来移至单独的标准文档中以使规范集中化,其借鉴了Socket的思想,通过单个TCP连接,为Web浏览器端与服务端之间提供了一种全双工通信机制。WebSocket协议旨在与现有的Web基础体系结构良好配合,基于此设计原则,协议规范定义了WebSocket协议握手流程需借助HTTP协议进行,并被设计工作在与HTTP(80)和HTTPS(443)相同的端口,也支持HTTP代理和中间件,以保证能完全向后兼容。

由于WebSocket本身只是一个应用层协议,原则上只要遵循这个协议的客户端均可使用,因此我们才得以将其运用到我们的Android客户端。

【更多音视频学习资料,点击下方链接免费领取↓↓,先码住不迷路~】

点击领取→音视频开发基础知识和资料包

什么是全双工通信?

简单来讲,就是通信双方(客户端和服务端)可同时向对方发送消息。为什么这一点很重要呢?因为传统的基于HTTP协议的通信是单向的,只能由客户端发起,服务端无法主动向客户端推送信息。一旦面临即时通讯这种对数据实时性要求很高的场景,当服务端有数据更新而客户端要获知,就只能通过客户端轮询的方式,具体又可分为以下两种轮询策略:

 

  • 短轮询 即客户端定时向服务端发送请求,服务端收到请求后马上返回响应并关闭连接。 优点:实现简单 缺点: 1.并发请求对服务端造成较大压力 2.数据可能没有更新,造成无效请求 3.频繁的网络请求导致客户端设备电量、流量快速消耗 4.定时操作存在时间差,可能造成数据同步不及时 5.每次请求都需要携带完整的请求头

 


 

长轮询 即服务端在收到请求之后,如果数据无更新,会阻塞请求,直至数据更新或连接超时才返回。 优点:相较于短轮询减少了HTTP请求的次数,节省了部分资源。 缺点: 1.连接挂起同样会消耗资源 2.冗余请求头问题依旧存在


 

与上述两个方案相比,WebSocket的优势在于,当连接建立之后,后续的数据都是以帧的形式发送。除非某一端主动断开连接,否则无需重新建立连接。因此可以做到:

1.减轻服务器的负担 2.极大地减少不必要的流量、电量消耗 3.提高实时性,保证客户端和服务端数据的同步 4.减少冗余请求头造成的开销


 


 

除了WebSocket,实现移动端即时通讯的还有哪些技术?

  • XMPP 全称(Extensible Messaging and Presence Protocol,可扩展通讯和表示协议),是一种基于XML的协议,它继承了在XML环境中灵活的发展性。 XMPP中定义了三个角色,客户端,服务器,网关。通信能够在这三者的任意两个之间双向发生。服务器同时承担了客户端信息记录,连接管理和信息的路由功能。网关承担着与异构即时通信系统的互联互通,异构系统可以包括SMS(短信),MSN,ICQ等。基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在之上传输XML。 优点 1.超强的可扩展性。经过扩展以后的XMPP可以通过发送扩展的信息来处理用户的需求。 2.易于解析和阅读。方便了开发和查错。 3.开源。在客户端、服务器、组件、源码库等方面,都已经各自有多种实现。 缺点 1.数据负载太重。过多的冗余标签、低效的解析效率使得XMPP在移动设备上表现不佳。

 

【更多音视频学习资料,点击下方链接免费领取↓↓,先码住不迷路~】

点击领取→音视频开发基础知识和资料包

 

应用场景举例:点对点单聊约球 我刚毕业时入职的公司曾接手开发一个线上足球约战的社交平台App项目,当时为了提高约球时的沟通效率,考虑为应用引入聊天模块,并优先实现点对点单聊功能。那时市面上的即时通讯SDK方案还尚未成熟,综合当时团队成员的技术栈,决定采用XMPP+Openfire+Smack作为自研技术搭建聊天框架。 Openfire基于XMPP协议,采用Java开发,可用于构建高效的即时通信服务器端,单台服务器可支持上万并发用户。Openfire安装和使用都非常简单,并利用Web进行管理。由于是采用开放的XMPP协议,因此可以使用各种支持XMPP协议的IM客户端软件登录服务。 Smack是一个开源的、易于使用的XMPP客户端Java类库,提供了一套可扩展的API。
  • MQTT 全称(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅模式的“轻量级”通讯协议,其构建于TCP/IP协议之上。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。 特点 1.基于发布/订阅模型。提供一对多的消息发布,解除应用程序耦合。 2.低开销。MQTT客户端很轻巧,只需要最少的资源,同时MQTT消息头也很小,可以优化网络带宽。 3.可靠的消息传递。MQTT定义了3种消息发布服务质量,以支持消息可靠性:至多一次,至少一次,只有一次。 4.对不可靠网络的支持。专为受限设备和低带宽、高延迟或不可靠的网络而设计。
应用场景举例:赔率更新、赛事直播聊天室 我第二家入职的公司的主打产品是一款提供模拟竞猜、赛事直播的体育类APP,其中核心的功能模块就是提供各种赛事的最新比分赔率数据,最初采用的即是上文所说的低效的HTTP轮询方案,效果可想而知。后面技术重构后改用了MQTT,极大地减少了对网络环境的依赖,提高了数据的实时性和可靠性。再往后搭建直播模块时,考虑到聊天室这种一对多的消息发布场景同样适合用MQTT解决,于是沿用了原先的技术方案扩展了新的聊天室模块。
  • WebSocket 而相较之下,WebSocket的特点包括: 1.**较少的控制开销。**在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。 2.**更好的二进制支持。**Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。 3.**可以支持扩展。**Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议,如以上所说的XMPP协议、MQTT协议等。
WebSocket协议在Android客户端的实现

 

实现WebSocket协议很简单,广为Android开发者使用的网络请求框架——OkHttp对WebSocket通信流程进行了封装,提供了简明的接口用于WebSocket的连接建立、数据收发、连接保活、连接关闭等,使我们可以专注于业务实现而无须关注通信细节,简单到我们只需要实现以下两步:

 

  • 创建WebSocket实例并提供一个URL以指定要连接的服务器地址
  • 提供一个WebSocket连接事件监听器,用于监听事件回调以处理连接生命周期的每个阶段

 

WebSocket URL的构成与Http URL很相似,都是由协议、主机、端口、路径等构成,区别就是WebSocket URL的协议名采用的是ws://和wss://,wss://表明是安全的WebSocket连接。


 

首先我们在项目中引入OkHttp库的依赖:

implementation("com.squareup.okhttp3:okhttp:4.9.0")

其次,我们须指定要连接的服务器地址,此处可以使用WebSocket的官方服务器地址:

 

/** WebSocket服务器地址 */ private var serverUrl: String = "ws://echo.websocket.org" @Synchronized fun connect() { val request = Request.Builder().url(serverUrl).build() val okHttpClient = OkHttpClient.Builder().callTimeout(20, TimeUnit.SECONDS).build() ... }

 

接着,我们调用OkHttpClient实例的newWebSocket(request: Request, listener: WebSocketListener)方法,该方法需传入两个参数,第一个是上文构建的Request对象,第二个是WebSocket连接事件的监听器,WebSocket协议包含四个主要的事件:

 

  • Open:客户端和服务器之间建立了连接后触发
  • Message:服务端向客户端发送数据时触发。发送的数据可以是纯文本或二进制数据
  • Close:服务端与客户端之间的通信结束时触发。
  • Error:通信过程中发生错误时触发。

 

每个事件都通过分别实现对应的回调来进行处理。OkHttp提供的监听器包含以下回调:

 

abstract class WebSocketListener { open fun onOpen(webSocket: WebSocket, response: Response) {} open fun onMessage(webSocket: WebSocket, text: String) {} open fun onMessage(webSocket: WebSocket, Bytes: ByteString) {} open fun onClosing(webSocket: WebSocket, code: Int, reason: String) {} open fun onClosed(webSocket: WebSocket, code: Int, reason: String) {} open fun onFAIlure(webSocket: WebSocket, t: Throwable, response: Response?) {} }
object WebSocketConnection : WebSocketListener() @Synchronized fun connect() { ... webSocketClient = okHttpClient.newWebSocket(request, this) } ... }

 

以上的事件通常在连接状态发生变化时被动触发,另一方面,如果用户想主动执行某些操作,WebSocket也提供了相应的接口以给用户显式调用。WebSocket协议包含两个主要的操作:

 

  • send( ) :向服务端发送消息,包括文本或二进制数据
  • close( ):主动请求关闭连接。

 

可以看到,OkHttp提供的WebSocket接口也提供了这两个方法:

 

interface WebSocket { ... fun send(text: String): Boolean fun send(bytes: ByteString): Boolean fun close(code: Int, reason: String?): Boolean ... }

 

当onOpen方法回调时,即是连接建立成功,可以传输数据了。此时我们便可以调用WebSocket实例的send()方法发送文本消息或二进制消息,WebSocket官方服务器会将数据通过onMessage(webSocket: WebSocket, bytes: ByteString)或onMessage(webSocket: WebSocket, text: String)回调原样返回给我们。

【更多音视频学习资料,点击下方链接免费领取↓↓,先码住不迷路~】

点击领取→音视频开发基础知识和资料包

WebSocket是如何建立连接的?

我们可以通过阅读OkHttp源码获知,newWebSocket(request: Request, listener: WebSocketListener)方法内部是创建了一个RealWebSocket实例,该类是WebSocket接口的实现类,创建实例成功后便调用connect(client: OkHttpClient)方法开始异步建立连接。

 

override fun newWebSocket(request: Request, listener: WebSocketListener): WebSocket { val webSocket = RealWebSocket( taskRunner = TaskRunner.INSTANCE, originalRequest = request, listener = listener, random = Random(), pingIntervalMillis = pingIntervalMillis.toLong(), extensions = null, // Always null for clients. minimumDeflateSize = minWebSocketMessageToCompress ) webSocket.connect(this) return webSocket }

 

连接建立的过程主要是向服务器发送了一个HTTP请求,该请求包含了额外的一些请求头信息:

 

val request = originalRequest.newBuilder() .header("Upgrade", "websocket") .header("Connection", "Upgrade") .header("Sec-WebSocket-Key", key) .header("Sec-WebSocket-Version", "13") .header("Sec-WebSocket-Extensions", "permessage-deflate") .build()

 

这些请求头的意义如下:

Connection: Upgrade:表示要升级协议

Upgrade: websocket:表示要升级到websocket协议。

Sec-WebSocket-Version:13:表示websocket的版本。如果服务端不支持该版本,需要返回一个Sec-WebSocket-Versionheader,里面包含服务端支持的版本号。

Sec-WebSocket-Key:与后面服务端响应首部的Sec-WebSocket-Accept是配套的,提供基本的防护,比如恶意的连接,或者无意的连接。

当返回的状态码为101时,表示服务端同意客户端协议转换请求,并将其转换为Websocket协议,该过程称之为Websocket协议握手(websocket Protocol handshake),协议升级完成后,后续的数据交换则遵照WebSocket的协议。

 

前面我们一直说「握手」,握手究竟指的是什么呢?在计算机领域的语境中,握手通常是指确保服务器与其客户端同步的过程。握手是WebSocket协议的基本概念。

 

为了直观展示,以上实例中传输的消息均以文本为例,WebSocket还支持二进制数据的传输,而这就要依靠「数据传输协议」来完成了,这是下一篇文章的内容,敬请期待。

总结

为了完成与服务端的双向通信,我们选取了WebSocket协议作为网络通信协议,并通过对比传统HTTP协议和其他相关的即时通讯技术,总结出,在为移动设备下应用选择的合适的网络通信协议时,可以有以下的参考标准:

 

  • 支持全双工通信
  • 支持二进制数据传输
  • 支持扩展
  • 跨语言、跨平台实现

 

同时,也对WebSocket协议在Android端的实现提供了示例,并对WebSocket协议握手流程进行了初步窥探,当然,这只是第一步,往后的心跳保活、断线重连、消息队列等每一个都可以单独作为一个课题,会在后面陆续推出的。



Tags:WebSocket   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  Search: WebSocket  点击:(19)  评论:(0)  加入收藏
浅谈WebSocket协议在Web领域的应用
Part 01、WebSocket是什么? WebSocket是一种在Web应用程序中提供双向通信的协议。它允许服务器主动向客户端推送数据,而不是像传统的HTTP请求-响应模式一样,客户端必须发送请...【详细内容】
2023-12-08  Search: WebSocket  点击:(200)  评论:(0)  加入收藏
WebSocket基本使用方法
WebSocket是一种双向、单套接字连接,使用WebSocket,那么请求就变成了打开WebSocket连接的单一请求,并且可以重用公客户端到服务器以及服务器到客户端的同一连接。WebSock减少延...【详细内容】
2023-12-02  Search: WebSocket  点击:(190)  评论:(0)  加入收藏
你不知道的Websocket协议,这次给你讲明白!
前言初次接触 websocket 的人,可能都会有这样的疑问:我们已经有了 http 协议,为什么还需要websocket协议?它带来了什么好处?原因是http每次请求只能由客户发起,而websocket最大特...【详细内容】
2023-11-29  Search: WebSocket  点击:(193)  评论:(0)  加入收藏
实时协作的秘诀:RabbitMQ与WebSockets的结合
实时协作是现代软件开发中非常重要的一个方面。为了实现实时协作,一种常见的做法是将消息队列与WebSocket技术相结合。其中,RabbitMQ是一个功能强大的消息队列系统,它能够有效...【详细内容】
2023-11-21  Search: WebSocket  点击:(177)  评论:(0)  加入收藏
WebSocket 魔法师:打造实时应用的无限可能
1、背景 在开发一些前端页面的时候,总是能接收到这样的需求:如何保持页面并实现自动更新数据呢?以往的常规做法,是前端使用定时轮询后端接口,获取响应后重新渲染前端页面,这种做法...【详细内容】
2023-11-09  Search: WebSocket  点击:(197)  评论:(0)  加入收藏
什么是WebSocket ,一文了解
WebSocket 允许我们创建“实时”应用程序,与传统 API 协议相比,该应用程序速度更快且开销更少。一、WebSocket 是如何工作的按照传统的定义,WebSocket是一种双工协议,主要用于客...【详细内容】
2023-10-03  Search: WebSocket  点击:(148)  评论:(0)  加入收藏
实时数据推送并非只有WebSocket一种选择
环境:SpringBoot2.7.16概述在Web应用中,有几种实时数据推送的选择方案,包括SSE(Server-Sent Events)、WebSocket、长轮询等。SSE是一种基于HTTP协议的服务器向客户端推送数据的技...【详细内容】
2023-09-27  Search: WebSocket  点击:(411)  评论:(0)  加入收藏
SpringBoot使用WebSocket实现即时消息
当以jar包形式运行时需要配置该bean,暴露我们配置的@ServerEndpoint;当我们以war独立tomcat运行时不能配置该bean。这里有个g-messages.js文件是我写的一个工具类,用来做连接及...【详细内容】
2023-08-14  Search: WebSocket  点击:(254)  评论:(0)  加入收藏
SpringBoot整合WebSocket详解
环境:Springboot3.0.5WebSocket介绍WebSocket协议RFC 6455提供了一种标准化的方式,通过一个TCP连接在客户端和服务器之间建立全双工、双向的通信通道。它是一个不同于HTTP的TC...【详细内容】
2023-08-09  Search: WebSocket  点击:(370)  评论:(0)  加入收藏
▌简易百科推荐
学生偷看“不良网站”,手机上3个痕迹无法清除,网友:咋不早说
众所周知,中国的常规教育中,总是“谈性色变”,但在这个信息爆炸的互联网时代,即便是一些年纪很小的孩子,也能轻易接触到一些所谓的不良网站,因此这一方面的教育缺失,其实是很可怕的...【详细内容】
2024-03-28    叶姐生活指南  Tags:不良网站   点击:(11)  评论:(0)  加入收藏
什么是网络中的路由器?核心功能解释
路由器是互联网连接的核心元素,是一种允许多个设备连接到互联网,并促进将数据包转发到各自的目标地址的设备。使用动态路由技术,路由器检查数据并在各种可用路径中选择最有效的...【详细内容】
2024-03-07    千家网  Tags:路由器   点击:(31)  评论:(0)  加入收藏
过年该不该升级Wi-Fi 7路由?看完就知道
打开电商网站不难发现,从2023年第三季度到现在,Wi-Fi 7路由器新品越来越多。而且价格不再是高高在上,已经基本和Wi-Fi 6路由价格差不多了。看到这些Wi-Fi 7新品路由,不少朋友就...【详细内容】
2024-02-27    中关村在线  Tags:Wi-Fi   点击:(37)  评论:(0)  加入收藏
聊聊 Kubernetes 网络模型综合指南
这篇详细的博文探讨了 Kubernetes 网络的复杂性,提供了关于如何在容器化环境中确保高效和安全通信的见解。译自Navigating the Network: A Comprehensive Guide to Kubernete...【详细内容】
2024-02-19  云云众生s  微信公众号  Tags:Kubernetes   点击:(39)  评论:(0)  加入收藏
SSL协议是什么?关于SSL和TLS的常见问题解答
SSL(安全套接字层)及其后继者TLS(传输层安全)是用于在联网计算机之间建立经过身份验证和加密的链接的协议。尽管SSL协议在 1999年已经随着TLS 1.0的发布而被弃用,但我们仍将这些...【详细内容】
2024-02-06  IDC点评网    Tags:SSL协议   点击:(69)  评论:(0)  加入收藏
从零开始了解网络协议:TCP/IP详解
从零开始了解网络协议:TCP/IP详解 在当今数字化的时代,网络协议已经成为我们生活中不可或缺的一部分。作为互联网的基础,网络协议规定了数据如何在不同的网络设备之间传输。TC...【详细内容】
2024-02-01    简易百科  Tags:TCP/IP   点击:(59)  评论:(0)  加入收藏
BGP路由属性:互联网路由的灵活控制器
在互联网的庞大网络中,边界网关协议(BGP)是确保不同自治系统(AS)间路由信息有效交换的关键协议。然而,BGP的功能远不止于此。其核心组成部分,即BGP路由属性,赋予了BGP强大的灵活性,使...【详细内容】
2024-01-26  诺诺爱生活    Tags:互联网路由   点击:(40)  评论:(0)  加入收藏
简易百科之什么是网络延迟?
简易百科之什么是网络延迟?随着互联网的普及和发展,网络已经成为我们生活中不可或缺的一部分。然而,我们在使用网络时可能会遇到一种情况,那就是网络延迟。那么,什么是网络延迟呢...【详细内容】
2024-01-24    简易百科  Tags:网络延迟   点击:(149)  评论:(0)  加入收藏
网络延迟与网络速度有什么区别?分享具体的答案
通常,许多人抱怨网速测试。速度还是不错的,但是他们玩游戏的时候怎么会卡住,还是断开连接等等问题,这一系列问题始终困扰着大家。那么,网络延迟与网络速度有什么区别呢?请不要担心...【详细内容】
2024-01-24  萌新小郭    Tags:网络延迟   点击:(51)  评论:(0)  加入收藏
揭秘IP地址的网络威胁与攻击类型
在当今数字化时代,网络攻击已经成为网络安全的一大挑战。IP地址,作为互联网通信的基础,也成为网络威胁和攻击的焦点之一。本文将深入探讨不同类型的网络威胁和攻击,以及如何防范...【详细内容】
2024-01-22  IP数据云    Tags:IP地址   点击:(78)  评论:(0)  加入收藏
站内最新
站内热门
站内头条