websocket-kit
websocket-kit copied to clipboard
Codable messages
Would be great to be able to specify a generic Message type on client.connect, that would auto-encode/decode if Codable conformance is present. This type could default to String.
onText could also be renamed onMessage.
Just a thought.
@lmcd Take a look at https://github.com/MihaelIsaev/AwesomeWS
This looks great, but I think I'd rather have support built right in as is in other parts of Vapor.
I agree, this would be a nice feature to have. Do you have any ideas on what a good API for that might look like @lmcd?
Something like (pseudocode):
extension WebSocket {
func send(_ data: T, encoder: JSONEncoder = JSONEncoder()) where T: Codable {
guard let data = try? encoder.encode(data), let dataString = String(data: data, encoding: .utf8) else {
return
}
send(dataString)
}
}
I'm interested in this bit of functionality, @tanner0101 is this something you are open to accepting contributions on? Do we need to nail down an API first?
Yeah any ideas you have for API would be appreciated.
I've been trying my hand at this, and I have an implementation that works for encoding a message when sending (can make a PR if this in itself is valuable enough), but am finding it much harder to implement some kind of automatic decoding.
I'd imagine the API within Vapor to be something like:
app.webSocket("socket") { req, ws in
ws.onMessage(Todo.self) { ws, todo in
todo.isCompleted.toggle()
ws.send(todo)
}
// fallback
ws.onText { ws, text in
let todo = Todo(name: text, completed: false)
ws.send(todo)
}
}
Where you could then register multiple onMessage callbacks for each type. There would be a performance cost iterating through each registered type and attempting to decode the text received, but you may just have to do the same outside of the library.
More importantly, I haven't been able to figure out a way to keep a collection of types and callbacks without losing type information.
We'd probably need to use a serialization format which includes a type identifier, like:
{
"type": "todo",
"data": { "completed": false, ... }
}
Then that could automatically lookup the Todo.self onMessage handler before attempting to decode. This all seems pretty opinionated though. We should research how other type-safe languages handle WebSocket messaging.
We'd probably need to use a serialization format which includes a type identifier, like:
And now it is the same as Bindable observer in my websocket-kit wrapper 🙂
Works perfectly btw 🙂