Android 使用 WebSocket 实现实时聊天

我曾有过这样的想法:WebSocket 是一种很难理解的东西,这种实时的东西需要我花一些时间来学习,而且不会那么容易,所以这个周末我尝试了一下,结果发现非常简单。因此,如果你和我一样,请阅读这篇文章,我们将在这里创建一个简单的聊天应用程序,并消除你对 WebSocket 的恐惧。

让我们先来了解一下什么是 WebSocket:

WebSocket 是一种通信协议,可在客户端(如网络浏览器)和服务器之间通过单个长期连接进行双向实时数据传输。与 HTTP 不同,WebSocket 可实现持续通信,而无需重复建立新连接。

Android 使用 WebSocket 实现实时聊天
图片来自wallarm

现在我们对 WebSocket 有了一些了解。

开始编码,首先创建一个数据类来保存信息:

data class ChatMessage(
    val message: String,
    val fromUserId: String
)

我们将使用 Tinder 的 Scarlet 来管理 WebSocket 通信。请在您的 app.gradle 文件中包含以下依赖项:

// Scarlet
implementation("com.tinder.scarlet:scarlet:0.1.12")
implementation("com.tinder.scarlet:websocket-okhttp:0.1.12")
implementation("com.tinder.scarlet:stream-adapter-rxjava2:0.1.12")

//RX
implementation("io.reactivex.rxjava2:rxjava:2.2.21")
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")
implementation("io.reactivex.rxjava2:rxkotlin:2.4.0")

// Gson
implementation("com.google.code.gson:gson:2.10.1")

不要忘记在 AndroidManifest 文件中添加上网权限。确保包含以下一行:

<uses-permission android:name="android.permission.INTERNET"/>

Scarlet 的灵感来自 Retrofit,因此我们将从创建界面开始。不过,与 Retrofit 不同的是,这个过程略有不同,涉及的注释较少。

interface ChatService {

    @Receive
    fun observeConnection(): Flowable<WebSocket.Event>

    @Send
    fun sendMessage(message: String)

}

进入 ViewModel 的实现,了解如何发送消息和观察 WebSocket 连接。首先创建一个 ChatService 实例。

private var chatService: ChatService = Scarlet.Builder()
        .webSocketFactory(
            OkHttpClient.Builder().build()
                .newWebSocketFactory("wss://free.blr2.piesocket.com/v3/1?api_key=${BuildConfig.websocketApiKey}&notify_self=1")
        )
        .addStreamAdapterFactory(RxJava2StreamAdapterFactory())
        .build().create<ChatService>()

使用 https://piehost.com/ 获取了一个免费的 WebSocket 服务器用于学习,也可以利用它并获取 API 密钥进行实验。

Android 使用 WebSocket 实现实时聊天

然后单击 “Test online “按钮并连接到 WebSocket。接下来回到 ViewModel,看看如何观察 WebSocket。

init {
    observerConnection()
}

private fun observerConnection() {
    Log.d(TAG, "Observing Connection")
    updateConnectionStatus(ConnectionStatus.CONNECTING)
    chatService.observeConnection().subscribe(
        { response ->
            Log.d(TAG, response.toString())
            onResponseReceived(response)
        },
        { error ->
            error.localizedMessage?.let { Log.e(TAG, it) }
        })
}

private fun onResponseReceived(response: WebSocket.Event) {
    when (response) {
        is OnConnectionOpened<*> ->
        updateConnectionStatus(ConnectionStatus.OPENED)

        is OnConnectionClosed ->
        updateConnectionStatus(ConnectionStatus.CLOSED)

        is OnConnectionClosing ->
        updateConnectionStatus(ConnectionStatus.CLOSING)

        is OnConnectionFailed ->
        updateConnectionStatus(ConnectionStatus.FAILED)

        is OnMessageReceived ->
        handleOnMessageReceived(response.message)
    }
}

WebSocket.Event 有五种类型:

  • OnConnectionOpened – 已接受并可开始传输信息。
  • OnConnectionClosed – 不再调用此监听器。
  • OnConnectionClosing – 不再传输传入的信息。
  • OnConnectionFailed – 当 web socket 已关闭时调用。
  • OnMessageReceived – 收到消息时调用。

发送消息非常简单,只需调用 ChatService 实例的 sendMessage 方法即可。

fun sendMessage(messageSent: () -> Unit) {
    val message = message()
    if (message.message.isEmpty()) return
    chatService.sendMessage(message.toJsonString())
        .also {
            messageSent()
        }
    addMessage(message)
    clearMessage()
}

现在 WebSocket 设置已完成,接下来可以继续设计 UI 即可,效果如下:

Android 使用 WebSocket 实现实时聊天

整的源代码可以在这个 Github 中找到。

作者:Vishal Kumar

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论