Musab
Posted on October 14, 2022
Hi Everyone
in this small article I'll show you to use socket.io with flutter riverpod
I'm assuming you already have basic knowledge about flutter riverpod and socketio
*first we will make node socket io server code *
1- make new folder name it as you like
2- run npm init -y
3- make file named server.js
paste the following code
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
//Whenever someone connects this gets executed
io.on('connection', function (socket) {
console.log('A user connected');
//Whenever someone disconnects this piece of code executed
socket.on('disconnect', function () {
console.log('A user disconnected');
});
socket.on('message', function (data) {
// when server receives event called message
// it convert the mesage to upper case
// then split it to array
var newMessage = [...data.toUpperCase()];
console.log(newMessage);
socket.emit('broadcast', newMessage);
})
});
// i'm exposing to to my wifi ip because i'm debugging using adb
http.listen(3000, '192.168.62.123', function () {
// to work locally use the followning line
// http.listen(3000, function () {
console.log('listening on *:3000');
});
then in terminal run node server.js
secondly we'll work on flutter application
1- create new flutter project
'flutter create my_project_name'
2- install packages , paste in pubsec.yaml
socket_io_client: *
flutter_riverpod: *
create class SocketService
class SocketService {
IO.Socket socket = IO.io(
// im using adb so i need to use my wifi ip
'http://192.168.62.123:3000',
IO.OptionBuilder()
.setTransports(['websocket']) // for Flutter or Dart VM
.disableAutoConnect() // disable auto-connection
// .setExtraHeaders({'foo': 'bar'}) // optional
.build());
initConnection() {
socket.connect();
socket.on('connection', (_) {
log('connect ${_.toString()}');
});
log('Trying Connection');
socket.onConnect((_) {
log('connect');
});
socket.onerror((_) {
log('Error Is ${_.toString()}');
});
}
sendMessage(message) {
socket.emit('message', message);
}
}
call the initConnection function on main
void main() {
// call initial connection in the main
// assuming you want the connection to be continuous
SocketService().initConnection();
}
create ConsumerWidget
class StreamProviderWithConsumer extends ConsumerWidget {
const StreamProviderWithConsumer({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(appBar: AppBar(), body: Center());
}
}
add stream provider
final providerOfSocket = StreamProvider.autoDispose((ref) async* {
StreamController stream = StreamController();
SocketService().socket.onerror((err) => log(err));
SocketService().socket.onDisconnect((_) => log('disconnect'));
SocketService().socket.on('fromServer', (_) => log(_));
SocketService().socket.on('broadcast', (data) {
stream.add(data);
log(data.toString());
});
SocketService().socket.onerror((_) {
log("Error IS ${_.toString()}");
});
/** if you using .autDisopose */
// ref.onDispose(() {
// // close socketio
// _stream.close();
// SocketService().socket.dispose();
// });
await for (final value in stream.stream) {
log('stream value => ${value.toString()}');
yield value;
}
});
watch stream provider inside the consumer widget
final message = ref.watch(providerOfSocket);
add next line
Center(
child: message.when(
data: (data) {
return Text(data.toString());
},
error: (_, __) {
log(_.toString());
return const Text('Error');
},
loading: () => const Text('Loading ')),
)
now when there 'broadcast' event fired , you'll The text will change
next I'll add TextEditingController and TextField
so i can send any string it will be processed and return back to me
the full
consumer widget code will be
class StreamProviderWithConsumer extends ConsumerWidget {
const StreamProviderWithConsumer({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
TextEditingController _controller = TextEditingController();
final message = ref.watch(providerOfSocket);
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
children: [
SizedBox(
height: 50,
width: 250,
child: TextField(
controller: _controller,
),
),
ElevatedButton(
onPressed: () => SocketService().sendMessage(_controller.text),
child: const Text('Send Message')),
const Divider(),
Center(
child: message.when(
data: (data) {
return Text(data.toString());
},
error: (_, __) {
log(_.toString());
return const Text('Error');
},
loading: () => const Text('Loading ')),
)
],
),
),
);
}
}
Posted on October 14, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.