Port of awesome JavaScript Node.js library - Socket.io-client v2.0.1~v3.0.3 - in Dart
socket.io-client-dart | Socket.io Server |
---|---|
v0.9.* ~ v1.* |
v2.* |
v2.* |
v3.* & v4.* |
Dart Server
import 'package:socket_io/socket_io.dart';
main() {
// Dart server
var io = Server();
var nsp = io.of('/some');
nsp.on('connection', (client) {
print('connection /some');
client.on('msg', (data) {
print('data from /some => $data');
client.emit('fromServer', "ok 2");
});
});
io.on('connection', (client) {
print('connection default namespace');
client.on('msg', (data) {
print('data from default => $data');
client.emit('fromServer', "ok");
});
});
io.listen(3000);
}
Dart Client
import 'package:socket_io_client/socket_io_client.dart' as IO;
main() {
// Dart client
IO.Socket socket = IO.io('http://localhost:3000');
socket.onConnect((_) {
print('connect');
socket.emit('msg', 'test');
});
socket.on('event', (data) => print(data));
socket.onDisconnect((_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));
}
To connect the socket manually, set the option autoConnect: false
and call .connect()
.
For example,
Socket socket = io('http://localhost:3000', OptionBuilder() .setTransports(['websocket']) // for Flutter or Dart VM .disableAutoConnect() // disable auto-connection .setExtraHeaders({'foo': 'bar'}) // optional .build() ); socket.connect();
Note that .connect()
should not be called if autoConnect: true
(by default, it's enabled to true), as this will cause all event handlers to get registered/fired twice. See Issue #33.
Socket socket = ... // Create socket.
socket.io.options['extraHeaders'] = {'foo': 'bar'}; // Update the extra headers.
socket.io..disconnect()..connect(); // Reconnect the socket manually.
Socket socket = ... // Create socket.
socket.onConnect((_) {
print('connect');
socket.emitWithAck('msg', 'init', ack: (data) {
print('ack $data') ;
if (data != null) {
print('from server $data');
} else {
print("Null") ;
}
});
});
These events can be listened on.
const List EVENTS = [
'connect',
'connect_error',
'connect_timeout',
'connecting',
'disconnect',
'error',
'reconnect',
'reconnect_attempt',
'reconnect_failed',
'reconnect_error',
'reconnecting',
'ping',
'pong'
];
// Replace 'onConnect' with any of the above events.
socket.onConnect((_) {
print('connect');
});
socket.on('eventName', (data) {
final dataList = data as List;
final ack = dataList.last as Function;
ack(null);
});
In Flutter env. not (Flutter Web env.) it only works with dart:io
websocket,
not with dart:html
websocket or Ajax (XHR), so in this case
you have to add setTransports(['websocket'])
when creates the socket instance.
For example,
IO.Socket socket = IO.io('http://localhost:3000',
OptionBuilder()
.setTransports(['websocket']) // for Flutter or Dart VM
.setExtraHeaders({'foo': 'bar'}) // optional
.build());
import 'dart:async';
// STEP1: Stream setup
class StreamSocket{
final _socketResponse= StreamController<String>();
void Function(String) get addResponse => _socketResponse.sink.add;
Stream<String> get getResponse => _socketResponse.stream;
void dispose(){
_socketResponse.close();
}
}
StreamSocket streamSocket =StreamSocket();
//STEP2: Add this function in main function in main.dart file and add incoming data to the stream
void connectAndListen(){
IO.Socket socket = IO.io('http://localhost:3000',
OptionBuilder()
.setTransports(['websocket']).build());
socket.onConnect((_) {
print('connect');
socket.emit('msg', 'test');
});
//When an event recieved from server, data is added to the stream
socket.on('event', (data) => streamSocket.addResponse);
socket.onDisconnect((_) => print('disconnect'));
}
//Step3: Build widgets with streambuilder
class BuildWithSocketStream extends StatelessWidget {
const BuildWithSocketStream({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: StreamBuilder(
stream: streamSocket.getResponse ,
builder: (BuildContext context, AsyncSnapshot<String> snapshot){
return Container(
child: snapshot.data,
);
},
),
);
}
}
- Refer to dart-lang/sdk#34284 issue. The workround is to use the following code provided by @lehno on #84
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() {
HttpOverrides.global = MyHttpOverrides();
runApp(MyApp());
}
- Refer to rikulo#108 issue.
Please use
socket.dispose()
instead ofsocket.close()
orsocket.disconnect()
to solve the memory leak issue on iOS.
- Refer to flutter/flutter#47606 (comment) issue.
By adding the following key into the to file *.entitlements
under directory macos/Runner/
<key>com.apple.security.network.client</key>
<true/>
For more details, please take a look at https://flutter.dev/desktop#setting-up-entitlements
The HTTP connections are disabled by default on iOS and Android, so here is a workaround to this issue, which mentioned on stack overflow
If you'd like to contribute back to the core, you can fork this repository and send us a pull request, when it is ready.
If you are new to Git or GitHub, please read this guide first.
Contribution of all kinds is welcome. Please read Contributing.md in this repository.
- Quire - a simple, collaborative, multi-level task management tool.
- KEIKAI - a web spreadsheet for Big Data.
- Thanks @felangel for rikulo#7
- Thanks @Oskang09 for rikulo#21
- Thanks @bruce3x for rikulo#25
- Thanks @Kavantix for rikulo#26
- Thanks @luandnguyen for rikulo#59
- Thanks @jorgefspereira for rikulo#177
- Thanks @fzyzcjy for rikulo#188
- Thanks @darwin-morocho for rikulo#189
- Thanks @chatziko for rikulo#237
- Thanks @Astray-git for rikulo#313
- Thanks @Astray-git for rikulo#310
- Thanks @Frank3K for rikulo#338