Flutter Riverpod를 Socket.io와 함께 사용하는 방법

안녕하세요 여러분
이 작은 기사에서는 Flutter riverpod와 함께 socket.io를 사용하는 방법을 보여 드리겠습니다.

Flutter riverpod 및 socketio에 대한 기본 지식이 이미 있다고 가정합니다.

*먼저 우리는 노드 소켓 io 서버 코드를 만들 것입니다*

1- 원하는 대로 새 폴더 이름 지정
2- 실행 npm init -y
3- server.js라는 파일 만들기

다음 코드 붙여넣기

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


그런 다음 터미널에서 node server.js를 실행합니다.

두 번째로 우리는 플러터 애플리케이션에 대해 작업할 것입니다.

1- 새로운 플러터 프로젝트 생성
'flutter create my_project_name'
2- 패키지 설치, pubsec.yaml에 붙여넣기
소켓_io_클라이언트: *
flutter_riverpod: *

클래스 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);
  }
}


메인에서 initConnection 함수를 호출합니다.

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


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


스트림 공급자 추가

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



소비자 위젯 내부의 스트림 제공자 보기final message = ref.watch(providerOfSocket);
다음 줄 추가

   Center(
              child: message.when(
                  data: (data) {
                    return Text(data.toString());
                  },
                  error: (_, __) {
                    log(_.toString());
                    return const Text('Error');
                  },
                  loading: () => const Text('Loading ')),
            )


이제 '브로드캐스트' 이벤트가 발생하면 텍스트가 변경됩니다.

다음으로 TextEditingController 및 TextField를 추가하겠습니다.
처리되어 나에게 다시 반환될 모든 문자열을 보낼 수 있습니다.

전체
소비자 위젯 코드는

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 ')),
            )
          ],
        ),
      ),
    );
  }
}


see the full code

좋은 웹페이지 즐겨찾기