Flutter WebSocket通信插件web_socket_io的使用

Flutter WebSocket通信插件web_socket_io的使用

基于Dart简单实现WebSocket。

WebSocket协议

请求握手
GET / HTTP/1.1
Host: 127.0.0.1:10086
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: k8ZJD7PN3mwawWDsd9V1OA==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
握手响应
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: WhwAE9ive8GXOhTDu6RlEunn4C0=

如何发布

dart pub publish --server=https://pub.dartlang.org

如何使用

服务端
class ServerDemo {
  final WebSocketServer _server = WebSocketServer();
  
  ServerDemo() {
    _server.onMessage = (event) {
      print(Utf8Decoder().convert(event.toList()));
    };
  }
  
  void play() {
    _server.bind('127.0.0.1', 10086);
  }

  void stop() {
    _server.close();
  }
}
客户端
class ClientDemo extends WebSocketProvider {
  late WebSocketClient _client;
  
  ClientDemo() {
    _client = WebSocketClient('ws://127.0.0.1:10086',
        provider: this, pingInterval: const Duration(seconds: 5));
    _client.connect();
  }

  void send(bool text) {
    if (text) {
      _client.send(OpCode.text, Uint8List.fromList('文本测试消息'.codeUnits));
    } else {
      _client.send(
          text ? OpCode.text : OpCode.binary, Utf8Encoder().convert('二进制测试消息'));
    }
  }

  [@override](/user/override)
  void onClosed(CloseCode code) {
    print('onClosed: $code');
  }

  [@override](/user/override)
  void onConnected(WebSocketChannel webSocket) {
    print('onConnected');
  }

  [@override](/user/override)
  void onText(String message, WebSocketChannel webSocket) {
    print('onText: $message');
  }

  [@override](/user/override)
  void onMessage(Uint8List message, WebSocketChannel webSocket) {
    print('onMessage: ${String.fromCharCodes(message)}');
  }

  [@override](/user/override)
  void onPing(Uint8List data, WebSocketChannel webSocket) {
    print('onPing');
  }

  [@override](/user/override)
  void onPong(Uint8List data, WebSocketChannel webSocket) {
    print('onPong');
  }
}

示例代码

import 'package:example/client_demo.dart';
import 'package:flutter/material.dart';

import 'server_demo.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late ServerDemo _server;
  late ClientDemo _client;
  bool _serverRunning = false;
  bool _clientRunning = false;

  [@override](/user/override)
  void initState() {
    _server = ServerDemo();
    _client = ClientDemo();

    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Expanded(child: _WorkPanel('服务端', _server)),
          Expanded(child: _WorkPanel('客户端', _client)),
        ],
      ),
    );
  }
}

class _WorkPanel extends StatefulWidget {
  String title;
  WebSocketProvider channel;
  _WorkPanel(this.title, this.channel);
  
  [@override](/user/override)
  State<_WorkPanel> createState() => _WorkPanelState();
}

class _WorkPanelState extends State<_WorkPanel> {
  var _running = false;
  ScrollController _controller = ScrollController();
  
  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    Widget current;
    current = Row(
      children: [
        SizedBox(width: 12),
        Text(widget.title),
        IconButton(
            onPressed: () {
              if (_running) {
                widget.channel.stop().then((value) {
                  setState(() {
                    _running = false;
                  });
                });
              } else {
                widget.channel.play().then((value) {
                  setState(() {
                    _running = true;
                  });
                });
              }
            },
            icon: Icon(_running ? Icons.stop : Icons.play_circle_fill)),
        TextButton(
            onPressed: () {
              widget.channel.send(true);
            },
            child: const Text(
              '发送文本消息',
              style: TextStyle(color: Colors.orange),
            )),
        TextButton(
            onPressed: () {
              widget.channel.send(false);
            },
            child: const Text('发送二进制消息'))
      ],
    );
    
    Widget list = ValueListenableBuilder(
        valueListenable: widget.channel.valueListenable(),
        builder: (ctx, List<String> value, widget) {
          Future.delayed(const Duration(microseconds: 200), () {
            _controller.jumpTo(_controller.position.maxScrollExtent);
          });
          return ListView.builder(
              shrinkWrap: true,
              controller: _controller,
              padding: const EdgeInsets.all(10),
              itemBuilder: (ctx, row) => Text(value[row]),
              itemCount: value.length);
        });
    
    current = Column(
      children: [current, Expanded(child: list)],
    );
    return current;
  }
}

更多关于Flutter WebSocket通信插件web_socket_io的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter WebSocket通信插件web_socket_io的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


web_socket_io 是一个用于在 Flutter 中进行 WebSocket 通信的插件。它基于 socket.io 协议,允许你在 Flutter 应用中进行实时双向通信。以下是使用 web_socket_io 插件的基本步骤和示例代码。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 web_socket_io 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  web_socket_io: ^0.5.0

然后运行 flutter pub get 来安装依赖。

2. 导入包

在你的 Dart 文件中导入 web_socket_io 包:

import 'package:web_socket_io/web_socket_io.dart';

3. 创建 WebSocket 连接

你可以使用 WebSocketIO 类来创建一个 WebSocket 连接。以下是一个简单的示例:

void connectToWebSocket() {
  // 创建 WebSocketIO 实例
  var socket = WebSocketIO('ws://your-websocket-url', options: {
    'transports': ['websocket'],
  });

  // 监听连接事件
  socket.on('connect', (_) {
    print('Connected to WebSocket');
  });

  // 监听消息事件
  socket.on('message', (data) {
    print('Received message: $data');
  });

  // 监听断开连接事件
  socket.on('disconnect', (_) {
    print('Disconnected from WebSocket');
  });

  // 连接 WebSocket
  socket.connect();
}

4. 发送消息

你可以使用 emit 方法向服务器发送消息:

void sendMessage(WebSocketIO socket, String message) {
  socket.emit('message', message);
}

5. 断开连接

当你不再需要 WebSocket 连接时,可以调用 disconnect 方法来断开连接:

void disconnectWebSocket(WebSocketIO socket) {
  socket.disconnect();
}

6. 完整示例

以下是一个完整的示例,展示了如何连接、发送消息、接收消息和断开连接:

import 'package:flutter/material.dart';
import 'package:web_socket_io/web_socket_io.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: WebSocketExample(),
    );
  }
}

class WebSocketExample extends StatefulWidget {
  [@override](/user/override)
  _WebSocketExampleState createState() => _WebSocketExampleState();
}

class _WebSocketExampleState extends State<WebSocketExample> {
  WebSocketIO? socket;

  [@override](/user/override)
  void initState() {
    super.initState();
    connectToWebSocket();
  }

  void connectToWebSocket() {
    socket = WebSocketIO('ws://your-websocket-url', options: {
      'transports': ['websocket'],
    });

    socket!.on('connect', (_) {
      print('Connected to WebSocket');
    });

    socket!.on('message', (data) {
      print('Received message: $data');
    });

    socket!.on('disconnect', (_) {
      print('Disconnected from WebSocket');
    });

    socket!.connect();
  }

  void sendMessage(String message) {
    socket!.emit('message', message);
  }

  void disconnectWebSocket() {
    socket!.disconnect();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WebSocket IO Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () => sendMessage('Hello, WebSocket!'),
              child: Text('Send Message'),
            ),
            ElevatedButton(
              onPressed: disconnectWebSocket,
              child: Text('Disconnect'),
            ),
          ],
        ),
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    disconnectWebSocket();
    super.dispose();
  }
}
回到顶部