Tectu / malloy

A cross-platform C++20 library providing embeddable server & client components for HTTP and WebSocket.
BSD 3-Clause "New" or "Revised" License
66 stars 8 forks source link

controller::make_websocket_connection() return value #42

Closed Tectu closed 3 years ago

Tectu commented 3 years ago

@0x00002a Something that got my attention while upgrading my applications that use malloy to the latest main: client::controller::make_websocket_connection() used to return an std::shared_ptr pointing to the connection. In the current design the return type is void instead.

In some of my applications I store the connection returned in a class member for later use. For example, if I have a server that provides a websocket connection for something like a heartbeat it's nice to keep the connection around so the client can disconnect/close the connection.

One might still grab the connection passed into the handler and store it that way but that seems.... "meh". I was wondering whether you have something to say on how to handle a situation like this?

0x00002a commented 3 years ago

Hmm, the reason the connection is not returned is that now the resolving is done by make_websocket_connection rather than in the connection object. This allows it to be more single-minded and lets it make sense as the server without some stuff "just in there for the client part". Because of this, we can't really return it straight off because we don't have it yet, the resolving is done via async. I suppose it could return a std::future but that runs into chainability issues and error reporting issues (if we fail to resolve, the connection object isn't valid).

My personal usage of the API currently hands the connection off to an object that does the session management and has access to a context which it registers the connection with. This is actually safer as well, since otherwise it is possible to use the connection before its actually connected yet, or even resolved the endpoint (I assume, unless asio does some magic here that stops that).

Tectu commented 3 years ago

My personal usage of the API currently hands the connection off to an object that does the session management and has access to a context which it registers the connection with.

I take it that you do this in the handler as there is currently no other way to "intercept" or "receive" an std::shared_ptr pointing to the connection? If so, you must have some logic in place in the handler to only do that on the first call of the handler as the handler gets invoked for every "data" received by the server?

0x00002a commented 3 years ago

If so, you must have some logic in place in the handler to only do that on the first call of the handler as the handler gets invoked for every "data" received by the server?

It shouldnt be, sorry I didn't clarify that in my writeup. The new behaviour is that the handler is invoked once per new connection with a pointer to that new connection waiting for accept (or stop to deny it). For router::add_websocket that is