- 创建WebSocket实例并提供一个URL以指定要连接的服务器地址
- 提供一个WebSocket连接事件监听器,用于监听事件回调以处理连接生命周期的每个阶段
WebSocket URL的构成与Http URL很相似,都是由协议、主机、端口、路径等构成,区别就是WebSocket URL的协议名采用的是ws://和wss://,wss://表明是安全的WebSocket连接 。
文章插图
首先我们在项目中引入OkHttp库的依赖:
【即时通讯协议选型:WebSocket协议】
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()
推荐阅读
- 黑客从Moola市场DeFi协议中窃取了840万美元
- 豪门|守护家产!妮可拉重署婚后协议,让大布签字,贝嫂否认攀上豪门
- 谁有资格签安置补偿协议? 安置补偿
- 终端陈列怎么搞? 终端陈列协议
- 詹妮弗·洛佩兹|emmm,他被婚前协议折腾垮了?
- 影视解说|《心动5》男4女4为爱奔赴,不顾7位数罚款?网友:不过是签了协议
- 读懂网络通信技术原理 网络通信技术
- IM OpenIM一个基于 Go 实现的开源即时通讯项目
- 心动5|《心动5》男4女4为爱奔赴,不顾7位数罚款?网友:不过是签了协议
- 山东即时高速路况来了,绕行方法快收好 山东高速路况查询