【发布时间】: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服务器有一个小技巧。仍在等待帮助,谢谢。
【问题讨论】:
标签: flutter dart websocket tcp