iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
0
Mobile Development

老姐好像要用 Kotlin 寫專案,能撐30天嗎?系列 第 22

各自努力的第二十二天:聊天室範例拼接(上)

建好題目和問答訊息的資料關係後,可以動手做問答聊天室了。

「姐,我先架了之前說的官網範例。你試試看 android 能不能接起來。」我提高音量,因為外面正傳來「少女的祈禱」。

老姐埋首於電腦前,鍵盤「達達」作響。「好,我把 toolbar 上的 navigation icon 和一些 navigation graph 處理完後就來接。」老姐這幾天正在做 App 側邊選單的功能。

我 Ktor 這邊還算順利,直接仿造範例程式碼 https://github.com/ktorio/ktor-samples/tree/63f5a9b9ab8c0576a1957565d1b09675a1292a0e/generic/samples/chat/src/backendMain/kotlin 是可以執行的。

https://ithelp.ithome.com.tw/upload/images/20201005/20129197NN2cJK2HoB.png

build.gradle 加上對應 Library。

implementation "io.ktor:ktor-websockets:$ktor_version"

ChatServer.kt 直接複製下來。 ChatApplication.kt 則是對應修改。

這行加在 Application.module 外:

private val server = ChatServer()

要安裝 Feature 。

    install(WebSockets) {
        pingPeriod = Duration.ofMinutes(1)
    }

routing block 裡加上主要邏輯, Session 改寫成客製化過的 LoginSession :

        webSocket("/ws") {
            val session= call.sessions.get<LoginSession>()

            // We check that we actually have a session. We should always have one,
            // since we have defined an interceptor before to set one.
            if (session == null) {
                close(CloseReason(CloseReason.Codes.VIOLATED_POLICY, "No session"))
                return@webSocket
            }

            // We notify that a member joined by calling the server handler [memberJoin]
            // This allows to associate the session id to a specific WebSocket connection.
            server.memberJoin(session.id.toString(), this)

            try {
                // We starts receiving messages (frames).
                // Since this is a coroutine. This coroutine is suspended until receiving frames.
                // Once the connection is closed, this consumeEach will finish and the code will continue.
                incoming.consumeEach { frame ->
                    // Frames can be [Text], [Binary], [Ping], [Pong], [Close].
                    // We are only interested in textual messages, so we filter it.
                    if (frame is Frame.Text) {
                        // Now it is time to process the text sent from the user.
                        // At this point we have context about this connection, the session, the text and the server.
                        // So we have everything we need.
                        transaction {
                            User.findById(session.id)?.let {
                                Chat.new {
                                    master = it
                                    message = frame.readText()
                                    topic = Topic.all().elementAt((0 until Topic.count()).random().toInt())
                                    createdAt = DateTime.now()
                                }
                            }
                        }
                        server.message(session.id.toString(), frame.readText())
                    }
                }
            } finally {
                // Either if there was an error, of it the connection was closed gracefully.
                // We notify the server that the member left.
                server.memberLeft(session.id.toString(), this)
            }
        }

測試過不影響原本寫的那幾個 http restful api 之後,隨便找了一個線上 websocket 測試網頁輸入路徑 ws://0.0.0.0:8080/ws ,確認我的 server 是能連接的。

https://ithelp.ithome.com.tw/upload/images/20201002/201291973fqvZ65Scr.png

也確認資料庫有存下送來的訊息。

https://ithelp.ithome.com.tw/upload/images/20201001/20129197mtMHeWtpxF.png

一小時後,老姐開始接聊天室,她參考了 https://ktor.io/docs/clients-websockets.html 的範例,可惜遇到了錯誤:
https://ithelp.ithome.com.tw/upload/images/20201001/20129197J2WKBw9Fn7.png

從老姐痛苦的神情可以判斷,今天解決不了這個問題。

沒關係,老姐!我們還有明天,明天繼續努力!


上一篇
家家烤肉的第二十一天:攔截 Route 製作專屬處理
下一篇
一改再改的第二十三天:聊天室範例拼接(下)
系列文
老姐好像要用 Kotlin 寫專案,能撐30天嗎?30

1 則留言

0
MumiRabbit
iT邦新手 5 級 ‧ 2020-10-05 11:13:31

不好意思,能請問您ktor參考的官網範例是參考哪篇嗎/images/emoticon/emoticon06.gif
還有有完整的github方便讓人參考嗎QAQ

Kate iT邦新手 5 級 ‧ 2020-10-05 11:28:54 檢舉

ktor 官網範例程式碼網址就是文章裡面提到的這個,裡面有兩個檔案。 https://github.com/ktorio/ktor-samples/tree/63f5a9b9ab8c0576a1957565d1b09675a1292a0e/generic/samples/chat/src/backendMain/kotlin

我要留言

立即登入留言