initial websocket implmentation#389
Conversation
Signed-off-by: Jess Frazelle <github@jessfraz.com>
Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Luqman Aden <me@luqman.ca>
Signed-off-by: Jess Frazelle <github@jessfraz.com>
Signed-off-by: Jess Frazelle <github@jessfraz.com>
Signed-off-by: Jess Frazelle <github@jessfraz.com>
Signed-off-by: Jess Frazelle <github@jessfraz.com>
|
Thanks Jess! Looks mostly good to me. cc @davepacheco for any more general dropshot stuff I might've missed |
|
I was thinking about it a bit and had an idea of how to allow for WebSocket out of the box but allow custom upgrades as well: Playing off your initial trait approach but not WebSocket specific: #[async_trait]
pub trait RequestUpgrade: Send + 'static {
type Upgraded;
async fn validate<B: Send + 'static>(
&self,
request: &mut Request<B>,
) -> Result<HttpResponseUpgraded, HttpError>;
async fn upgrade(
self,
upgraded: hyper::upgrade::Upgraded,
) -> Result<Self::Upgraded, HttpError>;
}
impl<Context: ServerContext> RequestContext<Context> {
// ....
pub async fn upgrade<F, R, U>(
&self,
upgrader: R,
func: F,
) -> Result<
(HttpResponseUpgraded, JoinHandle<Result<(), HttpError>>),
HttpError,
>
where
F: FnOnce(R::Upgraded) -> U + Send + 'static,
R: RequestUpgrade,
U: Future<Output = ()> + Send + 'static,
{
// ....
}
}So we'd provide a On the usage side that would look like: /// Echo a message back to the client.
async fn websocket(
rqctx: Arc<RequestContext<()>>,
-) -> Result<HttpResponseUpgradedWebSocket, HttpError> {
+) -> Result<HttpResponseUpgraded, HttpError> {
let (response, _) = rqctx
- .upgrade_websocket(None, |ws| {
+ .upgrade(WebSocketUpgrade::new(None), |ws| {
// Just echo all messages back...
let (tx, rx) = ws.split();
rx.forward(tx).map(|result| {Let me know if this makes sense? |
|
dope I was thinking similarly! |
|
fwiw, I took an approach with a somewhat lighter-touch API (as far as wrapping everything in our own API as is done here vs. simply re-exporting |
|
Thanks for starting the ball rolling on this and sorry for the slow movement. It looks like things have moved over to #403, which is more generic and incorporates it into the OpenAPI spec. I'll close this one. |
cc @luqmana
I'm not sure how to handle the error async. If we log to our logger, then the RequestContext needs to be borrowed as static.
fixes #387