Hi guys, I am new with ktor, I want to implement c...
# ktor
r
Hi guys, I am new with ktor, I want to implement chat server with ktor and websocket. I define a map to store socket connect, and I will get recipient by id from map when I receive message(JSON schema, include recipient id).
Copy code
val connections = Collections.synchronizedMap<String, Connection?>(mutableMapOf())

    webSocket("/chat") {

        val session = call.sessions.get<ChatSession>()
        if (session != null) {
            connections[session.id] = Connection(session.id, this)
        } else {
            close(CloseReason(CloseReason.Codes.VIOLATED_POLICY, "No session"))
            return@webSocket
        }

        send(Frame.Text("session id: ${session.id}"))

        incoming.consumeEach {
            val message = receiveDeserialized<Message>()

            <http://LOGGER.info|LOGGER.info>("incoming frame: ${<http://message.to|message.to>} - ${message.body}")

            connections[<http://message.to|message.to>]?.send(message.body)
                ?: send(Frame.Text("Not found session id: ${session.id}"))
        }

        connections.remove(session.id)
    }
But now, there is a confuse issue for me. when i create connect with server, I need to send message twice, and then client will just only receive second message, first message was lost.
Copy code
2023-08-12 22:54:31.961 [eventLoopGroupProxy-3-3] TRACE io.ktor.websocket.WebSocket - WebSocketSession(StandaloneCoroutine{Active}@958aea8) receiving frame Frame TEXT (fin=true, buffer len = 640)
2023-08-12 22:54:33.522 [eventLoopGroupProxy-3-6] TRACE io.ktor.websocket.WebSocket - WebSocketSession(StandaloneCoroutine{Active}@958aea8) receiving frame Frame TEXT (fin=true, buffer len = 642)
2023-08-12 22:54:33.524 [eventLoopGroupProxy-3-1] INFO  <http://c.g.redxiiikk.xxx.xxx|c.g.redxiiikk.xxx.xxx> - incoming frame: 41f0884dbfd29641 - Nostrum consequatur eveniet nemo et nemo. Quidem at eum perspiciatis voluptatem omnis et repudiandae. Et quia reiciendis quisquam est dolorem odio. Et omnis molestias id quis. Qui totam quod rerum.
Labore excepturi et voluptatem quia. Ratione veniam eius aspernatur animi. Ut atque et voluptas aliquam reprehenderit. Nam at nesciunt cum ut. Dolorem aut dolores impedit aperiam quia velit aut quam excepturi. Est dolorem voluptatem.
Necessitatibus et nihil deleniti dolorum nihil. Beatae suscipit et qui incidunt. Quae voluptatem dolorem corrupti voluptatem explicabo qui rerum nihil facere.
2023-08-12 22:54:33.524 [eventLoopGroupProxy-3-1] TRACE io.ktor.websocket.WebSocket - Sending Frame TEXT (fin=true, buffer len = 613) from session io.ktor.websocket.DefaultWebSocketSessionImpl@85fb615
there is a picture when I test my code by postman will help you understand my question.
a
Can you share the client code?
r
Hi @Aleksei Tirman [JB], thanks for you. Now I already known the reason for this problem after read source code and learn some knowledge about kotlin Coroutines. in my code, I consume webSocket message twice: 1. firstly is this line code:
incoming.consumeEach
,
incomming
is a ReceiveChannel, it will consume message automatic when message was send in channel. 2. and second, it is
val message = receiveDeserialized<Message>()
, I try to receive message from channel and deserialization message, and then will send message to client. so, this is why I have this problem, I am a new with kotlin and ktor. about the client code, I not write code to test my application. I directly use postman that it support webSocket, you can find detail in there: https://learning.postman.com/docs/sending-requests/websocket/websocket/. thanks for you again, hope you have a good day.