即时通讯协议选型:WebSocket协议( 三 )


 

  • 创建WebSocket实例并提供一个URL以指定要连接的服务器地址
  • 提供一个WebSocket连接事件监听器,用于监听事件回调以处理连接生命周期的每个阶段
 
WebSocket URL的构成与Http URL很相似,都是由协议、主机、端口、路径等构成,区别就是WebSocket URL的协议名采用的是ws://和wss://,wss://表明是安全的WebSocket连接 。
即时通讯协议选型: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()


推荐阅读