[Android] SSE 구현

릐라·2024년 10월 11일

SSE(Server-Sent-Event)

서버에서 클라이언트로 실시간 이벤트를 전달하는 단방향 통신 기술

OkHttp-SSE

https://github.com/square/okhttp/tree/master/okhttp-sse
Github에 따르면 아직 실험적으로 SSE를 제공하고 있기 때문에 정식 서비스에 이용하기는 어려울 것 같습니다
(캡스톤 디자인과 같은 단기성 프로젝트에는 유용할 것 같습니다)

implementation("com.squareup.okhttp3:okhttp-sse:$version")

implementation("com.launchdarkly:okhttp-eventsource:$version")

(이 포스트를 작성할 때는 okhttp-sse는 4.12.0, eventsource는 4.1.1 버전을 사용하였습니다)

// ServerClient
val okHttpClient = OkhttpClient().newBuilder().build()

// SSEClient
private val client = ServerClient.okHttpClient

fun startSse(eventSourceListener: EventSourceListener) {
	val request = Request.Builder().url("$SSE-Address").build()
	val factory = createFactory(client)

	val eventSource = factory.newEventSource(request, eventSourceListener)
}


// viewModel
val eventSourceListener = object: EventSourceListener() {
	override fun onOpen(eventSource: EventSource, response: Response) {
		super.onOpen(eventSource, response)
	}

	override fun onEvent(
		eventSource: EventSource,
		id: String?,
		type: String?,
		data: String
	) {
		val jsonObject = JsonParser.parseString(data).asJsonObject
		val dataObject = Gson().fromJson(jsonObject, DataObject::class.java)
       
		super.onEvent(eventSource, id, type, data)
	}
            
	override fun onFailure(eventSource: EventSource, t: Throwable?, response: Response?) {
		super.onFailure(eventSource, t, response)
	}

	override fun onClosed(eventSource: EventSource) {
		sseClient.startSse(this)
		super.onClosed(eventSource)
	}
}
        
sseClient.startSse()
// Spring SSE Emitter
SseEmitter emitter = new SseEmitter();
emitter.send(event().id("1").name("update").data(myObject));

위의 Spring의 SSE-Emitter는 id, name, data를 설정할 수 있는데 OkHttp-SSE에서는 이를 onEvent에서 각각 id, type, data로 받게되며 모두 String(String?) 타입으로 주어집니다.

data는 JsonParser와 Gson Converter로 원하는 Object(Model)로 변환 가능합니다.
SSE에서 여러 Model의 데이터를 수신하는 경우에는 id or type으로 판별하면 될 것 같습니다.

마지막으로 Spring 서버에서 30초마다 Reconnect를 하게 되었을 때 연결이 끊기게(onClosed) 됩니다.
이 때 sseClient.startSse(this)를 해주어 연결이 종료되었을 때 client에서 sse를 다시 시작해주는 방식을 사용하였습니다.
만약 Auto-Reconnect가 있다면 알려주시면 감사하겠습니다

0개의 댓글