본문 바로가기

프로그래밍/Android

[하톡시그널] Retrofit으로 Nest.js와 통신하는 과정에서 있던 일..

배경

매칭 시스템을 이렇게 구현하기로 했다.
매칭하기 버튼 클릭 -> (POST) 매칭 대기열에 추가 -> 반복 (POST) 매칭 됐는지 확인 (0.1초마다 보냄)
이렇게 확인하는 POST 요청을 3개 클라이언트에서 계속 보낸다.
매칭이 완료됐을 때, 확인 요청을 한 각 클라이언트에게 ROOM 정보를 준다.

문제

1. POST Response로 받을 데이터를 data class로 만들어 뒀다.
그 구조는 아래와 같다.

@Parcelize
data class roomInfo(
    val user1: userData?,
    val user2: userData?,
    val user3: userData?
) : Parcelable

@Parcelize
data class userData(
    val Id: String?,
    val nickname: String?,
    val icon: String?
) : Parcelable


@Parcelize
data class MatchingConfirmResponse(
    val msg: String?,
    var caller: String?,
    val remain_time: String?,
    val group_room_name: String?,
    val room_info: @RawValue roomInfo?,
    val question_list: Array<String>?
) : Parcelable

문제는 매칭하면 activity를 이동해야하고, putExtra를 이용해 데이터를 전달해줘야했다.
putExtra는 내가 만든 data class MatchingConfirmResponse를 전달해 줄 수 없으므로 확장해야 했고
위 코드처럼 @Parelize 주석과 Parcelable 설정을 통해 간단히 해결할 수 있었다.

 

주의: data class 안에 포함된 roomInfo는 @RawValue로 설정해줘야 했는데, 이건 자세히 알아보자
주의: MatchingConfirmResponse 안에 roomInfo안에 userData도 모두 parcelable해줘야 한다. (정확한 이유는 추가확인)

 

2.

private val retrofit = Retrofit
    .Builder()
    .addConverterFactory(MoshiConverterFactory.create(moshi).asLenient())
    .baseUrl(BASE_URL)
    .build()

retrofit 객체를 위와 같이 설정했다. (moshi 라이브러리를 이용했다.)
매칭 확인을 반복해서 보내기 때문에 matching이 성공했다고 정보를 받기 전에 또 POST를 보내게 되는것으로 생각이 되는데 (coroutine 설정이 문제인 것 같기도) 여기서 문제가 생겼다.

정리하면, POST 요청을 0.1s마다 보내는데 SUCCESS가 반환이 되고 activity를 전환하며 다음 행동을 수행하기도 전에 또 POST를 보내고 이 요청에 대해 null 값이 들어오게 됐다.
그래서 오류가 생겼고, null로 들어오는 response를 처리해주기 위해

val nullOnEmptyConverterFactory = object : Converter.Factory() {
    fun converterFactory() = this
    override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>, retrofit: Retrofit) = object : Converter<ResponseBody, Any?> {
        val nextResponseBodyConverter = retrofit.nextResponseBodyConverter<Any?>(converterFactory(), type, annotations)
        override fun convert(value: ResponseBody) = if (value.contentLength() != 0L) nextResponseBodyConverter.convert(value) else null
    }
}

위와 같은 ConverterFactory를 추가하여, retrofit 객체에 추가해줬다.

'프로그래밍 > Android' 카테고리의 다른 글

Jetpack Compose 정리1.  (0) 2021.12.27
Delegate란?  (0) 2021.12.22
[하톡시그널] Retrofit으로 서버와 연결하기  (0) 2021.11.19