Expand description
ConnectHandler trait and implementations, used to handle the connect event.
It has a flexible axum-like API, you can put any arguments as long as it implements the FromConnectParts trait.
You can also implement the FromConnectParts trait for your own types.
See the extract module doc for more details on available extractors.
Handlers must be async.
§Middlewares
ConnectHandlers can have middlewares, they are called before the connection
of the socket to the namespace and therefore before the handler.
Middlewares must be async and can be chained.
They are defined with the ConnectMiddleware trait which is automatically implemented for any
closure with up to 16 arguments with the following signature:
async FnOnce(*args) -> Result<(), E> where E: Display
Arguments must implement the FromConnectParts trait in the exact same way than handlers.
§Example with async closures
let (svc, io) = SocketIo::new_svc();
// Here the handler is async and extract the current socket and the auth payload
io.ns("/", async |io: SocketIo, s: SocketRef, TryData(auth): TryData<String>| {
println!("Socket connected on / namespace with id and auth data: {} {:?}", s.id, auth);
});
// Here the handler is async and only extract the current socket.
// The auth payload won't be deserialized and will be dropped
io.ns("/async_nsp", async |s: SocketRef| {
println!("Socket connected on /async_nsp namespace with id: {}", s.id);
});§Example with async non anonymous functions
async fn handler(s: SocketRef, TryData(auth): TryData<String>) {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("Socket connected on {} namespace with id and auth data: {} {:?}", s.ns(), s.id, auth);
}
let (svc, io) = SocketIo::new_svc();
// You can reuse the same handler for multiple namespaces
io.ns("/", handler);
io.ns("/admin", handler);§Example with middlewares
async fn handler(s: SocketRef) {
println!("socket connected on / namespace with id: {}", s.id);
}
#[derive(Debug)]
struct AuthError;
impl std::fmt::Display for AuthError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "AuthError")
}
}
impl std::error::Error for AuthError {}
async fn middleware(s: SocketRef, Data(token): Data<String>) -> Result<(), AuthError> {
println!("second middleware called");
if token != "secret" {
Err(AuthError)
} else {
Ok(())
}
}
async fn other_middleware(s: SocketRef) -> Result<(), AuthError> {
println!("first middleware called");
if s.req_parts().uri.query().map(|q| q.contains("secret")).unwrap_or_default() {
Err(AuthError)
} else {
Ok(())
}
}
let (_, io) = SocketIo::new_layer();
io.ns("/", handler.with(middleware).with(other_middleware));Traits§
- Connect
Handler - Define a handler for the connect event.
It is implemented for closures with up to 16 arguments. They must implement the
FromConnectPartstrait. - Connect
Middleware - Define a middleware for the connect event.
It is implemented for closures with up to 16 arguments.
They must implement the
FromConnectPartstrait and returnResult<(), E> where E: Display. - From
Connect Parts - A trait used to extract the arguments from the connect event.
The
Resultassociated type is used to return an error if the extraction fails, in this case theConnectHandleris not called.