Dart/Flutter WebSocket 服务器/客户端在同一侧无法正常工作
Posted
技术标签:
【中文标题】Dart/Flutter WebSocket 服务器/客户端在同一侧无法正常工作【英文标题】:Dart/Flutter WebSocket server/client is not working properly in the same side 【发布时间】:2020-07-02 20:18:19 【问题描述】:我正在尝试为我的兴趣开发一个 oauth2 演示。在演示中,当用户点击授权服务器时,授权服务器将重定向 url 返回给我。在我的服务器中,我为此重定向 url 保留了一个端点。在此端点中,我获取请求的查询参数并通过 web_socket_channel 连接到 websocket。连接后,我将查询参数数据发送到 Web 套接字。下面我将添加实现。
import 'package:aqueduct/aqueduct.dart';
import 'package:web_socket_channel/web_socket_channel.dart' as ws;
class AuthorizationController extends ResourceController
static final uri = Uri(scheme: 'ws',host: 'localhost',pathSegments: ['connect'],port: 8888);
@Operation.get()
Future<Response> manageRedirection()async
Map<String,dynamic> map = request.raw.uri.queryParameters;
sendToWs(map);
return Response.ok(map.toString());
void sendToWs(Map<String,dynamic> map)
final channel =ws.WebSocketChannel.connect(uri);
print("AuthorizationController: data -> $map");
channel.sink.add(map);
现在在服务器端(http 服务器的 /connect 端点为此保留)我升级传入请求并创建一个 WebSocketClient
实例并将该实例添加到列表中。下面我将展示升级部分和WebSocketClient
类
List<WebsocketClient> clients = [];
class Oauth2demoserverChannel extends ApplicationChannel
@override
Future prepare() async
logger.onRecord.listen((rec) => print("$rec $rec.error ?? "" $rec.stackTrace ?? """));
@override
Controller get entryPoint
final router = Router();
router
.route("/redirection")
.link(() => AuthorizationController());
router
.route("/connect")
.linkFunction((request) async
void handleWebSocket(WebSocket webSocket)
var newC = WebsocketClient(webSocket);
clients.add(newC);
print("clients map:$clients.asMap()");
// ignore: close_sinks
// ignore: unused_local_variable
final socket = await WebSocketTransformer.upgrade(request.raw)
.then(handleWebSocket);
return null;
);
return router;
以上部分是关于 Dart Aqueduct 框架及其路由的。我为授权服务器的重定向作业保留了/redirection
端点。我在该端点上获取数据,正如我们在第一个代码部分中看到的那样,我将自己连接到 ws://localhost:8888/connect
并添加数据。
现在我将向您展示这些WebSocketClientClass
。此类在构造函数中获取一个 websocket 实例并开始侦听。消息到达时; messageHandler
获取列表中的所有 Web 套接字客户端并广播消息。
import 'package:oauth2demoserver/oauth2demoserver.dart';
import 'package:oauth2demoserver/channel.dart' as ch;
class WebsocketClient
WebsocketClient(WebSocket ws)
_webSocket = ws;
_webSocket.listen(messageHandler,onError: errorHandler,onDone: finishHandler);
WebSocket _webSocket;
void messageHandler(dynamic data)
for(WebsocketClient wsc in ch.clients)
if( wsc != this)
wsc._webSocket.add(data);
void errorHandler(error)
print("err");
_webSocket.close();
void finishHandler()
print("finished");
_webSocket.close();
另一方面,我现在有一个单独的 Flutter 应用程序。在该应用程序中,我连接到ws://localhost:8888/connect
,我可以收听或添加一些内容,并且在服务器中WebSocketClient
可以处理消息并广播它。但是当我尝试使用一些查询参数点击http://localhost:8888/redirection
时,为该重定向新创建的WebSocketClient
实例不会进入messageHandler
函数,而是转到onDone
。因为这些消息永远不会进入任何渠道。我想知道为什么会这样,知道吗?我将添加一张图片,显示对/redirection
端点的调用的反应。
/redirection end point takes the query parameters end sends to web socket server for broadcating but it is not as we can see in this picture
注意:我还在 /redirect 端点尝试了另一个连接包,该客户端给出了错误代码 1005,它可能会有所帮助。
编辑:我也尝试过使用 javascript 和 python web socket 服务器。所以看起来服务器配置没有问题。我想关于http服务器有一个小技巧。仍在等待帮助,谢谢。
【问题讨论】:
【参考方案1】:我解决了这个问题。似乎在我将数据发送到 websocket 的 AuthorizationController(第一个代码部分)中,我需要对数据应用 json 编码。
channel.sink.add(json.encode(map));
【讨论】:
以上是关于Dart/Flutter WebSocket 服务器/客户端在同一侧无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章