使用Retrofit建立长连接

 

建立WebSocket连接

分为4个步骤:

  1. 创建OkHttpClient对象。
  2. 创建回调监听。回调监听是一个实现了WebSocketListener接口的对象。
  3. 创建Request对象,请求方法只能是GET。
  4. 调用OkHttpClient.newWebSocket(Request, WebSocketListener)发出请求。

HTTP协议升级为WebSocket协议

在OkHttpClient.newWebSocket()中:

  1. 创建RealWebSocket对象。
  2. 在创建RealWebSocket对象的过程中,创建了握手时使用的Key。Key是一个16字节长的随机数经过 Base64 编码得到的。
  3. 调用RealWebSocket.connect(),其中:
  4. 把协议设置为HTTP1.1;
  5. 向请求报头添加4个字段(省略了Sec-WebSocket-Protocol);
  6. 把Request对象和OkHttpClient对象封装为RealCall对象;
  7. 调用RealCall.enqueue(),在责任链中,只有CallServerInterceptor与HTTP的过程不同,它会在得到101响应码时把响应体置为空;
  8. 检查响应码是否是101,以及返回的Key是否是正确的。如果都是true,则握手成功;
  9. 获取连接(RealConnection对象)并把它封装为Streams对象;
  10. 创建WebSocketWriter对象,它可以向连接中写入数据;
  11. 创建ScheduledThreadPoolExecutor对象,它的作用是发送心跳包,及接受服务端发来的心跳包,及发送数据;
  12. 创建WebSocketReader对象,它可以从连接中读出数据;
  13. 启动while循环监听服务端请求,直到连接关闭。

Retrofit的心跳

发送

创建了一个大小为1的ScheduledThreadPoolExecutor对象,调用它的scheduleAtFixedRate()方法,每隔一段时间发送(默认不发送,设置间隔时间后发送)一个PingRunnable。在PingRunnable的执行体中,使用WebSocketWriter向连接写入一个心跳包。

接收

RealWebSocket.pongQueue(ArrayQueue)当接收到服务端发来的心跳包时,将向其中插入一个元素,并调用ScheduledThreadPoolExecutor.excute()执行writeRunnable。当writeRunnable执行时(不一定是接收到了心跳包,也可能是要发送数据),会从pongQueue中poll出一个元素,写入连接中作为回应。