sockets - Flutter `socket_io_client` 将 socket.on(event, data) 转换为流并在动态生成的流构建器中使用
问题描述
我有一个人列表,每个人都有自己的套接字连接。我正在使用 aListBuilder
为它们生成小部件列表,但我希望这些小部件中的每一个都监听此人的套接字连接是否已收到来自服务器的事件并相应地更新。我已经尝试了所有可以在网上找到的方法,但仍然找不到解决方案。
这是我尝试使用下面发布的解决方案之一
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:socket_io_client/socket_io_client.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<Person> sockets = [
Person(
name: 'Jon',
socket: io('http://localhost:3000', {
'transports': ['websocket'],
'autoConnect': false
}),
controller: StreamController<String>()),
Person(
name: 'Tim',
socket: io('http://localhost:3000', {
'transports': ['websocket'],
'autoConnect': false
}),
controller: StreamController<String>()),
Person(
name: 'Bob',
socket: io('http://localhost:3000', {
'transports': ['websocket'],
'autoConnect': false
}),
controller: StreamController<String>()),
];
// function to sink the data
void sinkToController(data, Person person) {
var message = '$data';
person.controller.sink.add(message);
}
void streamPerson(Person person) {
person.socket.connect();
person.socket.on('connect', (data) {
print('connected');
person.socket.on('serverMessage', (data) {
print('$data');
sinkToController(data, person);
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Socket test app"),
),
body: Container(
child: ListView.builder(
itemCount: 3,
itemBuilder: (context, index) {
streamPerson(sockets[index]);
return GestureDetector(
onTap: () => sockets[index].socket.emit('msg', 'this is me: ${sockets[index].name}'),
child: Container(
height: 300,
width: 350,
child: Column(
children: [
Text(sockets[index].name),
StreamBuilder<String>(
initialData: 'initial',
stream: sockets[index].controller.stream,
builder: (context, snapshot) {
return Text('${snapshot.data}');
},
)
],
),
),
);
})),
);
}
}
class Person {
String name;
Socket socket;
StreamController<String> controller;
Person({this.name, this.socket, this.controller});
}
但是,这不起作用,所以我希望是否有办法将 socket.on('event') 动态转换为流并在生成的流构建器中使用它。
结果是
先感谢您
解决方案
您应该使用 StreamController 为每个用户创建一个流。您可以在此处阅读更多相关信息:https ://dart.dev/articles/libraries/creating-streams#using-a-streamcontroller
^^^已编辑以在上面添加更好的答案
下面是我对发电机的初步尝试。不过,它可能行不通。
Stream userToLocationStream(User user) async* {
user.websocket.on('connect', (_) {
user.websocket.on('LocationChange', (data) {
yield data;
});
});
}
也许如果您决定遵循这条生成器路线而不是 StreamController,我关于生成器的演讲可能会有所帮助:https ://youtu.be/vPHxckiSmKY?t=4112
推荐阅读
- html - 带有 html_nodes ( rvest ) 的 R 循环没有捕获所有数据
- php - 浏览器不会缓存通过 php 代理加载的图像
- angular - ionic3 是否支持 dropbox javascript sdk?
- python - 收到错误“AttributeError:‘模块’对象没有属性‘Chrome’”
- javascript - 如果有用户,React Router 不显示登录
- c# - Discord.NET C# 更改 SocketMessage 的内容
- excel - application.ontime 未取消或在后台运行
- javascript - 如何使用 https.request 和 Node.JS 加载 JSON/API 数据
- cucumber - 同一黄瓜步骤定义的多个步骤
- c# - 在 wpf 的 tabpanel 中添加新按钮(添加按钮)时,TabControl 边框不隐藏