当前位置:   article > 正文

Flutter 中文文档:发起 WebSockets 请求

flutter websockets

640?wx_fmt=jpeg

除了普通的 HTTP 请求,你还可以通过 WebSockets 来连接服务器。WebSockets 可以以非轮询的方式与服务器进行双向通信。

640?wx_fmt=gif

在这里,你可以连接一个 由 websocket.org 提供的测试服务器。该服务器只会返回你发送的信息。

websocket.org 提供的测试服务器链接:https://www.websocket.org/echo.html

这个教程里包含以下步骤:

  1. 连接 WebSocket 服务器

  2. 监听来自服务器的消息

  3. 向服务器发送数据

  4. 关闭 WebSocket 连接

1. 连接 WebSocket 服务器

web_socket_channel 包提供了连接 WebSocket 服务器所需的一些工具。

该包提供的 WebSocketChannel 不仅可以让你监听到来自服务器的消息还可以让你向服务器推送消息。

Flutter 中,只用一行代码就可以创建一个连接到服务器的 WebSocketChannel

final channel = IOWebSocketChannel.connect('ws://echo.websocket.org');

2. 监听来自服务器的消息

建立了连接之后,你就可以监听来自服务器的消息了。
当你向测试服务器发送一条消息之后,它会将同样的消息发送回来。
在这个例子中,我们用  StreamBuilder  组件来监听新消息,用  Text  组件来展示它们。
  1. StreamBuilder(
  2.   stream: widget.channel.stream,
  3.   builder: (context, snapshot) {
  4.     return Text(snapshot.hasData ? '${snapshot.data}' : '');
  5.   },
  6. );
这样为什么可行?
WebSocketChannel  提供了一个来自服务器的  Stream  类消息。
这个  Stream  类是  dart:async  包的基本组成部分。 它提供了一个从数据源监听异步事件的方法。 和  Future  不一样的是, Future 只能返回一个单独的异步响应,而  Stream  类可以随着时间的推移传递很多事件。
StreamBuilder  组件会和  Stream  建立起连接,并且每当它接收到一个使用给定  builder  函数的事件时,就会通知 Flutter 去 rebuild。
3. 向服务器发送数据
要向服务器发送数据,可以使用  WebSocketChannel  提供的  sink  下的  add()  方法来发送信息。
channel.sink.add('Hello!');
这又是如何工作的呢
WebSocketChannel  提供了一个  Strea mSink  来向服务器推送消息。
这个  StreamSink  类提供了一个可以向数据源添加同步或者异步事件的通用方法。
4. 关闭 WebSocket 连接
当你使用完 WebSocket 之后,记得关闭这个连接。 要关闭这个 WebSocket 连接,只需要关闭  sink
channel.sink.close();
完整样例
  1. import 'package:flutter/foundation.dart';
  2. import 'package:web_socket_channel/io.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:web_socket_channel/web_socket_channel.dart';
  5. void main() => runApp(MyApp());
  6. class MyApp extends StatelessWidget {
  7.   @override
  8.   Widget build(BuildContext context) {
  9.     final title = 'WebSocket Demo';
  10.     return MaterialApp(
  11.       title: title,
  12.       homeMyHomePage(
  13.         title: title,
  14.         channelIOWebSocketChannel.connect('ws://echo.websocket.org'),
  15.       ),
  16.     );
  17.   }
  18. }
  19. class MyHomePage extends StatefulWidget {
  20.   final String title;
  21.   final WebSocketChannel channel;
  22.   MyHomePage({Key key, @required this.title, @required this.channel})
  23.       : super(key: key);
  24.   @override
  25.   _MyHomePageState createState() => _MyHomePageState();
  26. }
  27. class _MyHomePageState extends State<MyHomePage> {
  28.   TextEditingController _controller = TextEditingController();
  29.   @override
  30.   Widget build(BuildContext context) {
  31.     return Scaffold(
  32.       appBarAppBar(
  33.         titleText(widget.title),
  34.       ),
  35.       bodyPadding(
  36.         paddingconst EdgeInsets.all(20.0),
  37.         childColumn(
  38.           crossAxisAlignmentCrossAxisAlignment.start,
  39.           children: <Widget>[
  40.             Form(
  41.               childTextFormField(
  42.                 controller: _controller,
  43.                 decorationInputDecoration(labelText'Send a message'),
  44.               ),
  45.             ),
  46.             StreamBuilder(
  47.               stream: widget.channel.stream,
  48.               builder: (context, snapshot) {
  49.                 return Padding(
  50.                   paddingconst EdgeInsets.symmetric(vertical24.0),
  51.                   childText(snapshot.hasData ? '${snapshot.data}' : ''),
  52.                 );
  53.               },
  54.             )
  55.           ],
  56.         ),
  57.       ),
  58.       floatingActionButtonFloatingActionButton(
  59.         onPressed: _sendMessage,
  60.         tooltip'Send message',
  61.         childIcon(Icons.send),
  62.       ), // This trailing comma makes auto-formatting nicer for build methods.
  63.     );
  64.   }
  65.   void _sendMessage() {
  66.     if (_controller.text.isNotEmpty) {
  67.       widget.channel.sink.add(_controller.text);
  68.     }
  69.   }
  70.   @override
  71.   void dispose() {
  72.     widget.channel.sink.close();
  73.     super.dispose();
  74.   }
  75. }

640?wx_fmt=png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/268654
推荐阅读
相关标签
  

闽ICP备14008679号