DEV Community

Musab
Musab

Posted on

7

How to use Flutter Riverpod with Socket.io

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');
});
Enter fullscreen mode Exit fullscreen mode

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);
  }
}
Enter fullscreen mode Exit fullscreen mode

call the initConnection function on main

void main() {
  // call initial connection in the main
  // assuming you want the connection to be continuous
  SocketService().initConnection();
}
Enter fullscreen mode Exit fullscreen mode

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());
  }
}
Enter fullscreen mode Exit fullscreen mode

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;
  }
});

Enter fullscreen mode Exit fullscreen mode

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 ')),
            )
Enter fullscreen mode Exit fullscreen mode

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 ')),
            )
          ],
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

see the full code

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more