Struct socketioxide::SocketIo
source · pub struct SocketIo<A: Adapter = LocalAdapter>(/* private fields */);
Expand description
The SocketIo
instance can be cheaply cloned and moved around everywhere in your program.
It can be used as the main handle to access the whole socket.io context.
Implementations§
source§impl SocketIo<LocalAdapter>
impl SocketIo<LocalAdapter>
sourcepub fn builder() -> SocketIoBuilder
pub fn builder() -> SocketIoBuilder
Creates a new SocketIoBuilder
with a default config
sourcepub fn new_svc() -> (SocketIoService<NotFoundService>, SocketIo)
pub fn new_svc() -> (SocketIoService<NotFoundService>, SocketIo)
Creates a new SocketIoService
and a SocketIo
instance with a default config.
This service will be a standalone service that return a 404 error for every non-socket.io request.
It can be used as a Service
(see hyper example)
sourcepub fn new_inner_svc<S: Clone>(svc: S) -> (SocketIoService<S>, SocketIo)
pub fn new_inner_svc<S: Clone>(svc: S) -> (SocketIoService<S>, SocketIo)
Creates a new SocketIoService
and a SocketIo
instance with a default config.
It can be used as a Service
with an inner service
sourcepub fn new_layer() -> (SocketIoLayer, SocketIo)
pub fn new_layer() -> (SocketIoLayer, SocketIo)
Builds a SocketIoLayer
and a SocketIo
instance with a default config.
It can be used as a tower Layer
(see axum example)
source§impl<A: Adapter> SocketIo<A>
impl<A: Adapter> SocketIo<A>
sourcepub fn config(&self) -> &SocketIoConfig
pub fn config(&self) -> &SocketIoConfig
Returns a reference to the SocketIoConfig
used by this SocketIo
instance
sourcepub fn ns<C, T>(&self, path: impl Into<Cow<'static, str>>, callback: C)
pub fn ns<C, T>(&self, path: impl Into<Cow<'static, str>>, callback: C)
§Registers a ConnectHandler
for the given namespace.
- See the
connect
module doc for more details on connect handler. - See the
extract
module doc for more details on available extractors.
§Simple example with a sync closure:
#[derive(Debug, Serialize, Deserialize)]
struct MyData {
name: String,
age: u8,
}
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
// Register a handler for the "test" event and extract the data as a `MyData` struct
// With the Data extractor, the handler is called only if the data can be deserialized as a `MyData` struct
// If you want to manage errors yourself you can use the TryData extractor
socket.on("test", |socket: SocketRef, Data::<MyData>(data)| {
println!("Received a test message {:?}", data);
socket.emit("test-test", MyData { name: "Test".to_string(), age: 8 }).ok(); // Emit a message to the client
});
});
§Example with a closure and an acknowledgement + binary data:
#[derive(Debug, Serialize, Deserialize)]
struct MyData {
name: String,
age: u8,
}
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
// Register an async handler for the "test" event and extract the data as a `MyData` struct
// Extract the binary payload as a `Vec<Vec<u8>>` with the Bin extractor.
// It should be the last extractor because it consumes the request
socket.on("test", |socket: SocketRef, Data::<MyData>(data), ack: AckSender, Bin(bin)| async move {
println!("Received a test message {:?}", data);
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
ack.bin(bin).send(data).ok(); // The data received is sent back to the client through the ack
socket.emit("test-test", MyData { name: "Test".to_string(), age: 8 }).ok(); // Emit a message to the client
});
});
§Simple example with a closure:
#[derive(Debug, Deserialize)]
struct MyAuthData {
token: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct MyData {
name: String,
age: u8,
}
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef, Data(auth): Data<MyAuthData>| {
if auth.token.is_empty() {
println!("Invalid token, disconnecting");
socket.disconnect().ok();
return;
}
socket.on("test", |socket: SocketRef, Data::<MyData>(data)| async move {
println!("Received a test message {:?}", data);
socket.emit("test-test", MyData { name: "Test".to_string(), age: 8 }).ok(); // Emit a message to the client
});
});
sourcepub fn delete_ns<'a>(&self, path: impl Into<&'a str>)
pub fn delete_ns<'a>(&self, path: impl Into<&'a str>)
Deletes the namespace with the given path
sourcepub async fn close(&self)
pub async fn close(&self)
Gracefully closes all the connections and drops every sockets
Any on_disconnect
handler will called with DisconnectReason::ClosingServer
sourcepub fn of<'a>(&self, path: impl Into<&'a str>) -> Option<BroadcastOperators<A>>
pub fn of<'a>(&self, path: impl Into<&'a str>) -> Option<BroadcastOperators<A>>
Selects a specific namespace to perform operations on
§Example
let (_, io) = SocketIo::new_svc();
io.ns("custom_ns", |socket: SocketRef| {
println!("Socket connected on /custom_ns namespace with id: {}", socket.id);
});
// Later in your code you can select the custom_ns namespace
// and show all sockets connected to it
let sockets = io.of("custom_ns").unwrap().sockets().unwrap();
for socket in sockets {
println!("found socket on /custom_ns namespace with id: {}", socket.id);
}
sourcepub fn to(&self, rooms: impl RoomParam) -> BroadcastOperators<A>
pub fn to(&self, rooms: impl RoomParam) -> BroadcastOperators<A>
Selects all sockets in the given rooms on the root namespace.
Alias for io.of("/").unwrap().to(rooms)
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can select all sockets in the room "room1"
// and for example show all sockets connected to it
let sockets = io.to("room1").sockets().unwrap();
for socket in sockets {
println!("found socket on / ns in room1 with id: {}", socket.id);
}
sourcepub fn within(&self, rooms: impl RoomParam) -> BroadcastOperators<A>
pub fn within(&self, rooms: impl RoomParam) -> BroadcastOperators<A>
Selects all sockets in the given rooms on the root namespace.
Alias for :
io.of("/").unwrap().within(rooms)
io.to(rooms)
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can select all sockets in the room "room1"
// and for example show all sockets connected to it
let sockets = io.within("room1").sockets().unwrap();
for socket in sockets {
println!("found socket on / ns in room1 with id: {}", socket.id);
}
sourcepub fn except(&self, rooms: impl RoomParam) -> BroadcastOperators<A>
pub fn except(&self, rooms: impl RoomParam) -> BroadcastOperators<A>
Filters out all sockets selected with the previous operators which are in the given rooms.
Alias for io.of("/").unwrap().except(rooms)
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
socket.on("register1", |socket: SocketRef| {
socket.join("room1");
});
socket.on("register2", |socket: SocketRef| {
socket.join("room2");
});
});
// Later in your code you can select all sockets in the root namespace that are not in the room1
// and for example show all sockets connected to it
let sockets = io.except("room1").sockets().unwrap();
for socket in sockets {
println!("found socket on / ns in room1 with id: {}", socket.id);
}
sourcepub fn local(&self) -> BroadcastOperators<A>
pub fn local(&self) -> BroadcastOperators<A>
Broadcasts to all sockets only connected on this node (when using multiple nodes). When using the default in-memory adapter, this operator is a no-op.
Alias for io.of("/").unwrap().local()
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can select all sockets in the local node and on the root namespace
// and for example show all sockets connected to it
let sockets = io.local().sockets().unwrap();
for socket in sockets {
println!("found socket on / ns in room1 with id: {}", socket.id);
}
sourcepub fn timeout(&self, timeout: Duration) -> BroadcastOperators<A>
pub fn timeout(&self, timeout: Duration) -> BroadcastOperators<A>
Sets a custom timeout when broadcasting a message with an acknowledgement.
Alias for io.of("/").unwrap().timeout(duration)
§Panics
If the default namespace “/” is not found this fn will panic!
See SocketIoBuilder::ack_timeout
for the default timeout.
See emit_with_ack()
for more details on acknowledgements.
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can emit a test message on the root namespace in the room1 and room3 rooms,
// except for the room2 and wait for 5 seconds for an acknowledgement
io.to("room1")
.to("room3")
.except("room2")
.timeout(Duration::from_secs(5))
.emit_with_ack::<Value>("message-back", "I expect an ack in 5s!")
.unwrap()
.for_each(|(sid, ack)| async move {
match ack {
Ok(ack) => println!("Ack received, socket {} {:?}", sid, ack),
Err(err) => println!("Ack error, socket {} {:?}", sid, err),
}
});
sourcepub fn bin(&self, binary: Vec<Vec<u8>>) -> BroadcastOperators<A>
pub fn bin(&self, binary: Vec<Vec<u8>>) -> BroadcastOperators<A>
Adds a binary payload to the message.
Alias for io.of("/").unwrap().bin(binary_payload)
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can emit a test message on the root namespace in the room1 and room3 rooms,
// except for the room2 with a binary payload
io.to("room1")
.to("room3")
.except("room2")
.bin(vec![vec![1, 2, 3, 4]])
.emit("test", ());
sourcepub fn emit<T: Serialize>(
&self,
event: impl Into<Cow<'static, str>>,
data: T
) -> Result<(), BroadcastError>
pub fn emit<T: Serialize>( &self, event: impl Into<Cow<'static, str>>, data: T ) -> Result<(), BroadcastError>
Emits a message to all sockets selected with the previous operators.
Alias for io.of("/").unwrap().emit(event, data)
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can emit a test message on the root namespace in the room1 and room3 rooms,
// except for the room2
io.to("room1")
.to("room3")
.except("room2")
.emit("Hello World!", ());
sourcepub fn emit_with_ack<V>(
&self,
event: impl Into<Cow<'static, str>>,
data: impl Serialize
) -> Result<AckStream<V>, Error>
pub fn emit_with_ack<V>( &self, event: impl Into<Cow<'static, str>>, data: impl Serialize ) -> Result<AckStream<V>, Error>
Emits a message to all sockets selected with the previous operators and waits for the acknowledgement(s).
To get acknowledgements, an AckStream
is returned.
It can be used in two ways:
- As a
Stream
: It will yield all theAckResponse
with their corresponding socket id received from the client. It can useful when broadcasting to multiple sockets and therefore expecting more than one acknowledgement. If you want to get the socket from this id, useio::get_socket()
. - As a
Future
: It will yield the firstAckResponse
received from the client. Useful when expecting only one acknowledgement.
If the packet encoding failed a serde_json::Error
is immediately returned.
If the socket is full or if it has been closed before receiving the acknowledgement,
an AckError::Socket
will be yielded.
If the client didn’t respond before the timeout, the AckStream
will yield
an AckError::Timeout
. If the data sent by the client is not deserializable as V
,
an AckError::Serde
will be yielded.
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
socket.on("test", |socket: SocketRef, Data::<Value>(data), Bin(bin)| async move {
// Emit a test message in the room1 and room3 rooms,
// except for the room2 room with the binary payload received
let ack_stream = socket.to("room1")
.to("room3")
.except("room2")
.bin(bin)
.emit_with_ack::<String>("message-back", data)
.unwrap();
ack_stream.for_each(|(sid, ack)| async move {
match ack {
Ok(ack) => println!("Ack received, socket {} {:?}", sid, ack),
Err(err) => println!("Ack error, socket {} {:?}", sid, err),
}
}).await;
});
});
sourcepub fn sockets(&self) -> Result<Vec<SocketRef<A>>, A::Error>
pub fn sockets(&self) -> Result<Vec<SocketRef<A>>, A::Error>
Gets all sockets selected with the previous operators.
It can be used to retrieve any extension data from the sockets or to make some sockets join other rooms.
Alias for io.of("/").unwrap().sockets()
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can select all sockets in the room "room1"
// and for example show all sockets connected to it
let sockets = io.within("room1").sockets().unwrap();
for socket in sockets {
println!("found socket on / ns in room1 with id: {}", socket.id);
}
sourcepub fn disconnect(&self) -> Result<(), Vec<DisconnectError>>
pub fn disconnect(&self) -> Result<(), Vec<DisconnectError>>
Disconnects all sockets selected with the previous operators.
Alias for io.of("/").unwrap().disconnect()
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can disconnect all sockets in the root namespace
io.disconnect();
sourcepub fn join(self, rooms: impl RoomParam) -> Result<(), A::Error>
pub fn join(self, rooms: impl RoomParam) -> Result<(), A::Error>
Makes all sockets selected with the previous operators join the given room(s).
Alias for io.of("/").unwrap().join(rooms)
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can for example add all sockets on the root namespace to the room1 and room3
io.join(["room1", "room3"]).unwrap();
sourcepub fn rooms(&self) -> Result<Vec<Room>, A::Error>
pub fn rooms(&self) -> Result<Vec<Room>, A::Error>
Gets all room names on the current namespace.
Alias for io.of("/").unwrap().rooms()
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
let io2 = io.clone();
io.ns("/", move |socket: SocketRef| async move {
println!("Socket connected on /test namespace with id: {}", socket.id);
let rooms = io2.rooms().unwrap();
println!("All rooms on / namespace: {:?}", rooms);
});
sourcepub fn leave(self, rooms: impl RoomParam) -> Result<(), A::Error>
pub fn leave(self, rooms: impl RoomParam) -> Result<(), A::Error>
Makes all sockets selected with the previous operators leave the given room(s).
Alias for io.of("/").unwrap().join(rooms)
§Panics
If the default namespace “/” is not found this fn will panic!
§Example
let (_, io) = SocketIo::new_svc();
io.ns("/", |socket: SocketRef| {
println!("Socket connected on / namespace with id: {}", socket.id);
});
// Later in your code you can for example remove all sockets on the root namespace from the room1 and room3
io.leave(["room1", "room3"]).unwrap();