OkHttp SSE 模块详解

OkHttp SSE 模块详解

什么是 Server-Sent Events (SSE)

Server-Sent Events (SSE) 是一种基于 HTTP 的服务器推送技术,允许服务器通过单个 HTTP 连接向客户端发送事件流。SSE 建立了一个长连接,服务器可以通过这个连接持续地向客户端推送数据,而无需客户端重复发起请求。

核心特点

  • 单向通信:服务器向客户端推送数据,客户端不能通过同一连接向服务器发送数据

  • 基于 HTTP :使用标准 HTTP 协议,Content-Type 为 text/event-stream

  • 自动重连:客户端在连接断开后会自动尝试重新连接

  • 事件 ID:支持事件 ID,可以在重连后恢复之前的状态

  • 基于纯文本:使用简单的文本格式传输数据

SSE 数据格式示例

vbnet 复制代码
event: userconnect
data: {"username": "bobby", "time": "02:33:48"}
id: 1

event: usermessage
data: {"username": "bobby", "message": "Hi everyone!"}
id: 2

SSE vs WebSocket

特性 SSE WebSocket
通信方向 单向(服务器到客户端) 双向
协议 HTTP WebSocket(初始握手基于HTTP)
复杂度 简单 相对复杂
自动重连 原生支持 需要自行实现
数据格式 文本 文本或二进制
跨域限制 受同源策略限制 较少限制
适用场景 实时通知、新闻推送、股票行情 聊天应用、多人游戏、协作工具

OkHttp SSE 模块的功能和用途

OkHttp SSE 模块是 OkHttp 库的扩展,提供了在 Android 和 Java 应用中使用 SSE 的能力。它封装了 SSE 的连接建立、事件解析和错误处理等复杂逻辑,让开发者可以简单地实现服务器推送功能。

主要功能

  1. 建立 SSE 连接:通过 HTTP 请求建立与 SSE 服务器的连接

  2. 事件解析:解析服务器发送的事件流,提取事件类型、数据和ID

  3. 自动重连:在连接断开时自动重新连接

  4. 事件监听:通过 EventSourceListener 接收和处理事件

  5. 连接管理:提供取消连接的方法

使用场景

SSE 技术和 OkHttp SSE 模块适用于以下场景:

  1. 实时通知系统:如新邮件提醒、系统通知等

  2. 实时数据更新:股票价格、体育比分、天气更新等

  3. 社交媒体动态:新的评论、点赞、关注等通知

  4. 日志流:实时查看服务器日志

  5. 进度更新:长时间运行任务的进度报告

优势

  1. 简单易用:相比 WebSocket,SSE 实现更简单,API 更直观

  2. HTTP 兼容:使用标准 HTTP,可以利用现有的 HTTP 基础设施(代理、缓存等)

  3. 轻量级:协议简单,资源消耗较小

  4. 自动重连:内置重连机制,提高了连接的可靠性

  5. 与 OkHttp 集成:可以复用 OkHttp 的连接池、拦截器等功能

代码示例

以下是使用 OkHttp SSE 模块的完整示例:

kotlin 复制代码
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.sse.EventSource
import okhttp3.sse.EventSourceListener
import okhttp3.sse.EventSources
import java.util.concurrent.TimeUnit

fun main() {
    // 1. 创建 OkHttpClient
    val client = OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .readTimeout(90, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .build()
    
    // 2. 创建 EventSource.Factory
    val factory = EventSources.createFactory(client)
    
    // 3. 创建 Request
    val request = Request.Builder()
        .url("https://example.com/sse-endpoint")
        .header("Accept", "text/event-stream")
        .build()
    
    // 4. 创建 EventSourceListener
    val listener = object : EventSourceListener() {
        override fun onOpen(eventSource: EventSource, response: Response) {
            println("SSE connection opened: ${response.code}")
        }
        
        override fun onEvent(
            eventSource: EventSource,
            id: String?,
            type: String?,
            data: String
        ) {
            println("Event received:")
            println("  id: $id")
            println("  type: $type")
            println("  data: $data")
            
            // 处理不同类型的事件
            when (type) {
                "update" -> handleUpdate(data)
                "notification" -> showNotification(data)
                null -> handleDefaultEvent(data)
            }
        }
        
        override fun onClosed(eventSource: EventSource) {
            println("SSE connection closed normally")
        }
        
        override fun onFailure(eventSource: EventSource, t: Throwable?, response: Response?) {
            println("SSE connection failed: ${t?.message}")
            response?.let { println("Response code: ${it.code}") }
            
            // 可以在这里实现自定义的重连逻辑
        }
    }
    
    // 5. 创建并启动 EventSource
    val eventSource = factory.newEventSource(request, listener)
    
    // 应用运行...
    
    // 6. 在适当的时候取消连接
    // eventSource.cancel()
}

// 事件处理函数
fun handleUpdate(data: String) {
    println("Processing update: $data")
}

fun showNotification(data: String) {
    println("Showing notification: $data")
}

fun handleDefaultEvent(data: String) {
    println("Processing default event: $data")
}

OkHttp SSE 实现原理

OkHttp 的 SSE 模块通过以下组件和流程实现 SSE:

核心组件

  1. EventSource 接口:定义 SSE 连接的基本操作

  2. EventSourceListener:处理连接状态和接收事件的回调

  3. RealEventSource:EventSource 的实际实现

  4. ServerSentEventReader:解析 SSE 事件流

实现流程

  1. 连接建立
  • RealEventSource 使用 OkHttp 的 Call 接口发起 HTTP 请求

  • 验证响应的 Content-Type 是否为 text/event-stream

  • 建立长连接并获取响应体的 Source

  1. 事件解析
  • ServerSentEventReaderSource 读取数据

  • 按照 SSE 规范解析事件行(event、data、id、retry)

  • 当收集到完整事件时,通过 EventSourceListener.onEvent() 回调通知客户端

  1. 自动重连
  • 当连接断开时,根据服务器指定的 retry 值或默认值进行重连

  • 重连时携带上次接收到的最后一个事件 ID,服务器可以据此发送错过的事件

  1. 错误处理
  • 网络错误、解析错误等通过 EventSourceListener.onFailure() 通知客户端

  • 客户端可以在此实现自定义的错误处理和重连策略

  1. 资源释放
  • 当调用 EventSource.cancel() 或发生不可恢复的错误时

  • 关闭网络连接,释放相关资源

  • 通过 EventSourceListener.onClosed()onFailure() 通知客户端

关键实现细节

  • 线程处理:事件解析和回调在 OkHttp 的后台线程池中进行,避免阻塞主线程

  • 缓冲管理:使用 Okio 库高效处理 I/O 操作和缓冲区管理

  • 连接复用:利用 OkHttp 的连接池机制,可能复用底层 TCP 连接

  • 拦截器兼容:完全兼容 OkHttp 的拦截器链,支持日志、认证等功能

通过这种实现,OkHttp SSE 模块提供了一个高效、可靠且易于使用的 SSE 客户端,同时充分利用了 OkHttp 的网络处理能力和扩展性。

相关推荐
程序员JerrySUN5 小时前
Valgrind Memcheck 全解析教程:6个程序说明基础内存错误
android·java·linux·运维·开发语言·学习
经典19926 小时前
mysql 性能优化之Explain讲解
android·mysql·性能优化
Kiri霧7 小时前
Kotlin集合与空值
android·开发语言·kotlin
Glacien9 小时前
compose动画从底层基础到顶层高级应用(三)核心API之--Transition
android
亿刀9 小时前
为什么要学习Flutter编译过程
android·flutter
suqingxiao9 小时前
android虚拟机(AVD)报错The emulator process for AVD xxx has terminated
android
whysqwhw9 小时前
OkHttp Cookie 处理机制全解析
android
Evan_ZGYF丶10 小时前
【RK3576】【Android14】ADB工具说明与使用
android·驱动开发·android14·rk3576
幻雨様10 小时前
UE5多人MOBA+GAS 番外篇:移植Lyra的伤害特效(没用GameplayCue,因为我失败了┭┮﹏┭┮)
android·ue5
狂浪天涯11 小时前
Android 16 显示系统 | 从View 到屏幕系列 - 4 | GraphicBuffer & Gralloc
android·操作系统