Skip to content

Configurable SocketConfig for servers #101

@gbaranski

Description

@gbaranski

Adding configurable socket through SocketConfig could allow users to change the default heartbeat duration, timeout and message. It is already implemented on the client side.

For tungstenite:

async fn accept(
&self,
stream: TcpStream,
handle: &enfync::builtin::native::TokioHandle,
) -> Result<(Socket, Request), Error> {
let mut req0 = None;
let callback = |req: &http::Request<()>,
resp: http::Response<()>|
-> Result<http::Response<()>, ErrorResponse> {
let mut req1 = Request::builder()
.method(req.method().clone())
.uri(req.uri().clone())
.version(req.version());
for (k, v) in req.headers() {
req1 = req1.header(k, v);
}
let Ok(body) = req1.body(()) else {
return Err(ErrorResponse::default());
};
req0 = Some(body);
Ok(resp)
};
let socket = match self {
Acceptor::Plain => {
let socket = tokio_tungstenite::accept_hdr_async(stream, callback).await?;
Socket::new(socket, SocketConfig::default(), handle.clone())
}
#[cfg(feature = "native-tls")]
Acceptor::NativeTls(acceptor) => {
let tls_stream = acceptor.accept(stream).await?;
let socket = tokio_tungstenite::accept_hdr_async(tls_stream, callback).await?;
Socket::new(socket, SocketConfig::default(), handle.clone())
}
#[cfg(feature = "rustls")]
Acceptor::Rustls(acceptor) => {
let tls_stream = acceptor.accept(stream).await?;
let socket = tokio_tungstenite::accept_hdr_async(tls_stream, callback).await?;
Socket::new(socket, SocketConfig::default(), handle.clone())
}
};
let Some(req_body) = req0 else {
return Err("invalid request body".into());
};
Ok((socket, req_body))
}
}

and for Axum, on_upgrade_with_config() function is not used anywhere.

pub fn on_upgrade_with_config<E: ServerExt + 'static>(
self,
server: Server<E>,
socket_config: SocketConfig,
) -> Response {
self.ws.on_upgrade(move |socket| async move {
let handle = enfync::builtin::native::TokioHandle::try_adopt()
.expect("axum server runner only works in a tokio runtime");
let socket = Socket::new(socket, socket_config, handle);
server.accept(socket, self.request, self.address);
})
}

It comes down into three options:

  • Configuration through Server::create(), global options for all incoming sessions.
  • Configuration through Session::create(), but it could be a little bit tricky, as Socket is already created when the Session::create() is called.
  • Configuration through mentioned above on_upgrade_with_config() in case of Axum. It would work only for Axum

First option doesn't seem bad? Unless you want to have different configuration for each of the clients connected to your server, but is it actually necessary?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions