https://kotlinlang.org logo
#ktor
Title
# ktor
f

Francis Mariano

03/11/2023, 10:24 PM
hello everyone. Is it possible to implement a server running a websocket and normal api??? For example, I want create a api with POST method which sending a message for a client via websocket.
b

Big Chungus

03/11/2023, 10:26 PM
Sure, server can have separate endpoints serving different protocols
You can't have both, post and websocket under the same endpoint though (nor should you)
f

Francis Mariano

03/11/2023, 10:44 PM
ok....I thought was possible. Now, I am with difficult how structure both protocols. hypothetically I open a websocket between the server and a client. Lets consider the documentation example:
Copy code
routing {
    webSocket("/echo") {
        send("Please enter your name")
        for (frame in incoming) {
            frame as? Frame.Text ?: continue
            val receivedText = frame.readText()
            if (receivedText.equals("bye", ignoreCase = true)) {
                close(CloseReason(CloseReason.Codes.NORMAL, "Client said BYE"))
            } else {
                send(Frame.Text("Hi, $receivedText!"))
            }
        }
    }
}
When my post endpoint receives a message I would like to send that message for the client established in websocket connection.
Copy code
route("api/host") {
    post("") {
       val host = call.receive<HostDto>()
       // send host via websocket
    }
}
I do not know how to do that. Anyone have some any idea, please???
c

Casey Brooks

03/11/2023, 10:58 PM
HTTP is a stateless protocol, and outside of a single connection so are websockets. They intentionally do not have any knowledge about each other, there’s no automatic connection between HTTP requests an websockets. If you have them defined on the same server and running in the same process, you could use something like a
Channel
to send data from the HTTP call to an active Websocket connection, but this is not advisable in any kind of real-world scenario, since in production your HTTP calls and websockets might be routed to different server processes. For real-world applications, you’d probably want to use something like Redis to communicate between HTTP calls and websockets
Copy code
// this channel is a singleton
val channel = Channel<HostDto>()

routing {
    webSocket("/echo") {
        launch {
            for(hostDto in channel) { 
                send(hostDto.toString())
            }
        }

        send("Please enter your name")
        for (frame in incoming) {
            frame as? Frame.Text ?: continue
            val receivedText = frame.readText()
            if (receivedText.equals("bye", ignoreCase = true)) {
                close(CloseReason(CloseReason.Codes.NORMAL, "Client said BYE"))
            } else {
                send(Frame.Text("Hi, $receivedText!"))
            }
        }
    }
}
route("api/host") {
    post("") {
       val host = call.receive<HostDto>()
       channel.send(host)
    }
}
f

Francis Mariano

03/11/2023, 11:12 PM
wow, sounds great. ok, I have no much experience with web development. The problem you described can happen in VPS server where I create the application with embedded server ??
a

Adel Ayman

03/12/2023, 1:02 AM
Hi , @Francis Mariano Your question has 2 parts 1-can I implement http and websocket together? Yes you can , but you have to create endpoints for web socket and separated endpoints for http 2-can I send message from http request to web-socket? No, you can’t. Http send data to a client over a single HTTP connection Web socket is creating realtime connection between server and client As we said Http and web-socket are different protocols so you can’t link them together
12 Views