current position:Home>Introduction and practice of fluent (55): play websocket with provider

Introduction and practice of fluent (55): play websocket with provider

2022-01-27 03:50:37 Manon on the island

This is my participation 8 The fourth of the yuegengwen challenge 18 God , Check out the activity details :8 Yuegengwen challenge

Preface

In practical applications , We often encounter data flow processing , For example, monitoring real-time location will generate real-time location information flow , such as Socket Need to monitor when communicating Socket Data flow . For data flow , stay Flutter Referred to as Stream, and Provider by Stream Specially designed a StreamProvider To monitor changes in data flow , When the data stream generates new data, it will notify the listening component to refresh . In this article, we will introduce how to use StreamProvider monitor WebSocket data .

The knowledge points of this design are as follows :

  • WebSokcet Client encapsulation plug-in socket_io_client Use .
  • StreamProvider monitor Socket data .

In order to make the program run normally , Simple has been added to the back-end code socket, Use and socket_io_client Supporting service end socket.io,npm The address is socket.io, Version is 4.1.3. Be careful Flutter There is version compatibility in the plug-in , The version currently under development supporting this version :^2.0.0-beta.4-nullsafety.0( Stable version 1.0.1 The plug-in does not support the server side 4.1.3 edition ). The back-end source code address is : Back end supporting source code .

socket_io_client Introduce

socket_io_client It's very popular Socket Client plug-ins ,javascript There's a corresponding version .socket_io_client Yes Dart Of Socket It was packaged , Thus simplifying socket Use .

The way to create a connection is as follows , among $host and $port Corresponding host name and port , The following is the configuration parameters . Use websocket when , You need to specify the transports( Array ) Its elements include websocket,autoConnect Whether to automatically connect after creation , Automatically connect by default .forceNew Whether to create a new... Every time Socket object , If false( Default ) The old connection will be used ( Without closing ). Here we use a new one every time Socket object This is because we have to close the connection after exiting the page .

_socket = SocketIO.io('ws://$host:$port', <String, dynamic>{
  'transports': ['websocket'],
  'autoConnect': true,
  'forceNew': true
});
 Copy code 

Once created, you can set Socket Event response callback method , Commonly used by the following methods :

  • onConnect(EventHandler handler): The connection is established successfully. Callback ;
  • onConnectTimeout(EventHandler handler): Connection timeout callback ;
  • onConnectError(EventHandler handler): Connection error callback ;
  • onError(EventHandler handler): Callback when an error occurs ;
  • on(String event, (EventHandler handler): Subscribe to messages for the specified event , When the server sends the message of this event, it can receive... In this function .
  • onDisconnect(EventHandler handler): Callback when disconnected ;
  • connect/disconnect: Active connection / Disconnect method ;
  • open/close: Opening and closing methods .

The point is to create a connection , When the received data is added to a stream processing object .Flutter Provides StreamController Class processing Stream object .StreamController Only one subscriber is allowed , have access to sink Attribute add Method to add new stream data , After adding, its subscribers will be notified of new data generation . So we can use StreamProvider To subscribe to this stream .

Let's build a Socket Management category StreamSocket, The code is as follows :

class StreamSocket {
  final _socketResponse = StreamController<String>();

  Stream<String> get getResponse => _socketResponse.stream;

  final String host;
  final int port;
  late final Socket _socket;

  StreamSocket({required this.host, required this.port}) {
    _socket = SocketIO.io('ws://$host:$port', <String, dynamic>{
      'transports': ['websocket'],
      'autoConnect': true,
      'forceNew': true
    });
  }

  void connectAndListen() {
    _socket.onConnect((_) {
      debugPrint('connected');
    });

    _socket.onConnectTimeout((data) => debugPrint('timeout'));
    _socket.onConnectError((error) => debugPrint(error.toString()));
    _socket.onError((error) => debugPrint(error.toString()));
    _socket.on('msg', (data) {
      _socketResponse.sink.add(data);
    });
    _socket.onDisconnect((_) => debugPrint('disconnect'));
  }

  void sendTextMessage(String message) {
    _socket.emit('msg', message);
  }

  void close() {
    _socketResponse.close();
    _socket.disconnect().close();
  }
}
 Copy code 

StreamProvider application

StreamProvider Application and FutureProvider,ChangeNotifierProvider similar , Also divided into create and value Two forms :

// create  form 
StreamProvider({
  Key? key,
  required Create<Stream<T>?> create,
  required T initialData,
  ErrorBuilder<T>? catchError,
  UpdateShouldNotify<T>? updateShouldNotify,
  bool? lazy,
  TransitionBuilder? builder,
  Widget? child,
}) 
  
// value  form 
StreamProvider.value({
  Key? key,
  required Stream<T>? value,
  required T initialData,
  ErrorBuilder<T>? catchError,
  UpdateShouldNotify<T>? updateShouldNotify,
  bool? lazy,
  TransitionBuilder? builder,
  Widget? child,
}) 
 Copy code 

Here we first use a StatefulWidget To manage StreamSocket Initialization and Socket The closing of the , And the actual business components are used in two Provider The parcel , One is StreamProvider, One is MessageModel.StreamProvider For automatic monitoring Socket The flow of data , And displayed on the interface ;MessageModel At present, it is only used to send messages .

class _SocketClientWrapperState extends State<SocketClientWrapper> {
  final StreamSocket streamSocket = StreamSocket(host: '127.0.0.1', port: 3001);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Stream Provicer'),
      ),
      body: Stack(
        alignment: Alignment.bottomCenter,
        children: [
          StreamProvider<String>(
            create: (context) => streamSocket.getResponse,
            initialData: '',
            child: StreamDemo(),
          ),
          ChangeNotifierProvider<MessageModel>(
            child: MessageReplyBar(messageSendHandler: (message) {
              streamSocket.sendTextMessage(message);
            }),
            create: (context) => MessageModel(),
          ),
        ],
      ),
    );
  }

  @override
  void initState() {
    streamSocket.connectAndListen();
    super.initState();
  }

  @override
  void dispose() {
    streamSocket.close();
    super.dispose();
  }
}
 Copy code 

Here we use Stack The input bar of the message MessageReplyBar Fixed at the bottom , It should be noted that , If you want the input bar to float automatically with the keyboard , You need to put it in Scaffold Of body in , Otherwise, it will always be fixed at the bottom and blocked .

StreamDemo and MessageReplyBar Both components are simple , The business logic is MessageReplyBar Click the send button to send the message through Socket Send it to the server . then StreamDemo The echo StreamProvider from Socket Received server message .

Running effect

We cooperate with the print log of the server to see the operation effect : You can see the establishment of the connection 、 Send a message 、 The process of receiving messages and disconnecting is normal .

 Screen Recording 2021-08-17  Afternoon 10.18.16.gif

The source code has been uploaded to : Status management related codes - null safety edition .

summary

This article introduces Provider Of StreamProvider Flow state management , At the same time, it introduces socket_io_client The plug-in realizes the connection with the server WebSocket signal communication , adopt StreamProvider Subscribe to stream data , And notify the interface to refresh , The non invasion of the interface layer is realized Socket Data presentation . This one is relatively simple , More about the use of the two tools , In the next article, we use these two tools to implement an instant chat application .


I'm Manon on the island , WeChat official account , This is a Flutter Introduction and actual combat A column for , Corresponding source code, please see here :Flutter Introduction and actual combat column source code .

: If you think you have something to gain, please praise and encourage !

: Collect articles , It's convenient to look back !

: Comment exchange , Make progress with each other !

copyright notice
author[Manon on the island],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/01/202201270350306647.html

Random recommended