hello channel, a quick question about websockets i...
# ktor
h
hello channel, a quick question about websockets in ktor for example in node js(socket.io), we can do something like this: socket.broadcast.to(socket).emit('event_name', JSON.stringify(data)) the event_name can be used to differentiate between event types on client side, how to do something like this in ktor? all I can see in ktor examples is that you send message as: socket.send(Frame(data)) Is there a neat way to send the event type along with the data?
a
You can encode an event in a frame itself and write methods that hide this detail. Also, there is a feature request to support socket.io interface out of the box.
h
just for clarification, so you mean that I can have a base class(that'll hold the event value and the generic data value) and based on the event value, I parse the data value, right? or is there a better way?
a
I mean to have an extension function for a
SendChannel<Frame>
object that internally encodes event in a
Frame
. Here is an example:
Copy code
suspend fun SendChannel<Frame>.emit(event: String, frame: Frame) {
    val packet = BytePacketBuilder().apply {
        append(event)
        writeFully(frame.data)
    }.build()

    send(Frame.Binary(true, packet.readBytes()))
}
And the calling side will look like this:
Copy code
client.webSocket("<ws://0.0.0.0:4444/socket>") {
    outgoing.emit("event", Frame.Text("hello"))
}
h
thanks alot man, I'll give it a try
It works on the server side, I have tried connecting to the websocket from android using the socketio java client library but it's not connecting, working through postman but not from the app, I have enabled the internet permissions in manifest file and also allowed clear text traffic, still not connecting from android so I am assuming that ktor websockets aren't compatible with socketio clients, is that so? also if I use ktor client on android to connect to the websockets, how can I extract the event using ktor websocket client?
a
They should be compatible but I'm not sure. I suggest using a network protocol analyzer like WireShark to determine if the Websockets frames are actually sent or not. To extract an event from the frame you need to understand how Socket.IO encodes it by analyzing frames.
h
I am trying ktor client now on Android, but I am not sure how can I extract the event when I receive the frames on Android side from this:
Copy code
val packet = BytePacketBuilder().apply {
        append(event)
        writeFully(frame.data)
    }.build()
on android, I can do something like
Copy code
socket?.incoming
    ?.receiveAsFlow()
    ?.filter { it is Frame.Binary }
now how to separate data and event from this stream? because the length will be different for the event string
a
This was just an example 🙂 You need to encode events in a way to deterministically read them on the other side.
h
Oh I see, pardon for my ignorance, I am a sort of a newbie here, undergrad student still what if I make each event string of length of 32, and for shorter strings, I append some character like # to fulfill the length, and on android side, when I get the event string of length 32, I can do something like event.replace("#", "") or is there a neater way?
a
I would encode the length of an event string in the first byte (like in Pascal strings) so you could have events with up to 255 characters.
h
I see, that's neat I'll give it shot, thanks