WebSocket
WebSocket is a communication protocol that enables real-time, full-duplex, bidirectional data exchange between a client and a server over a single, long-lived connection. It is commonly used in web applications to facilitate interactive features like live chat, online gaming, and real-time updates, as it allows for efficient and low-latency data transfer without the overhead of constantly opening and closing connections. WebSocket is especially well-suited for scenarios where instant communication and data synchronization between client and server are crucial.
Usage
1. Create websocket service with redis adapter
class WebsocketService implements DoxService {
@override
void setup() {
Redis sub = Redis();
Redis pub = sub.duplicate();
WebsocketServer io = WebsocketServer(Dox());
io.adapter(WebsocketRedisAdapter(
subscriber: sub,
publisher: pub,
));
}
}
Info
While running with multiple isolate(multithread), the Dox WebSocket require Redis adapter which require ioredis
package to function. Currently, Dox WebSocket only supports the Redis adapter. And if you do not want to use any adapter, please set total isolate value to 1
in lib/config/app.dart
to function properly.
2. Register websocket service to dox app/config/services.dart
List<DoxService> services = <DoxService>[
... /// other services
WebsocketService,
];
3. Create websocket controller
dox create:controller SocketController -ws
import 'package:dox_core/dox_core.dart';
import 'package:dox_websocket/dox_websocket.dart';
class ChatWebSocketController {
intro(WebsocketEmitter emitter, dynamic message) {
// sent message to chart room but exclude the sender
emitter.room('chat').emitExceptSender('intro', message);
}
noti(WebsocketEmitter emitter, dynamic message) {
// sent message to chart room including the sender
emitter.room('chat').emit('noti', message);
}
}
Note
As webSocket maintains an open connection, there is no requirement to send back any values from your controller method.
4. register websocket route and events
ChatWebSocketController controller = ChatWebSocketController();
Router.websocket('ws', (WebsocketEvent event) {
// when client sent an event called `intro`,
// it will execute `controller.intro` method
event.on('intro', controller.intro);
// when client sent an event called `noti`,
// it will execute `controller.noti` method
event.on('noti', controller.noti);
});
Info
You can register websocket routes on lib/routes/web.dart
or you can also create custom websocket router and register in lib/config/app.dart
. Both option will create a websocket url on ws://127.0.0.1:{port}/ws
.
Note
You also have the option to register WebSocket routes for multiple paths, rather than just the default /ws
route.
Client Usage
You have the option to utilize either the built-in browser WebSocket or any WebSocket library for clients. The key requirement is that when sending data, it must be in the form of a JSON string containing both event
and message
attributes. Refer to the example below for clarification.
Example with Dart
import 'dart:io';
// The event name that is listening in your routes
// Eg. DoxWebsocket.on('intro', controller.intro);
String event = 'intro';
// Message can be any type such as int, float, map, string etc..
String message = "Mingalaba!";
// Encoding to json formatted string
var data = jsonEncode({
"event": event,
"message": message,
});
String url = 'ws://localhost:3000/ws';
WebSocket socket = await WebSocket.connect(url);
socket.add(data);
// If you would like to join the room, please use event name `joinRoom`
var joinRoomData = jsonEncode({
"event": "joinRoom",
"message": "chat", // sent room name as message
});
// Sent message to join the chat room
socket.add(joinRoomData);
Example with javascript
For Handling with javascript, we suggested you to use below library. https://github.com/dartondox/dox-web-socket-client
import DoxWebsocket from '@dartondox/websocket';
const socket = DoxWebsocket('ws://127.0.0.1:3000/ws', {
maxRetries: 18, retryAfter: 2000
})
socket.onConnected(() => {
console.log(socket.id)
})
socket.onError(() => {
console.log('socket error')
})
// Listen in client for intro event that will sent from the server
socket.on('intro', (msg) => {
console.log(msg)
})
socket.onClose(() => {
console.log('socket closed')
})
function sendMessage(message) {
socket.emit('intro', message)
}
SocketEmitter
room
Set the room before emit to client
emitter.room('chat').emit('event-name', message);
emit
Emit to all the client connected to the same websocket route.
emitter.emit('event-name', message);
emitExceptSender
Emit to all the client connected to the same websocket route except the sender.
emitter.emitExceptSender('event-name', message);