im试图为我的兴趣开发一个oauth2演示。在演示中,当用户点击授权服务器时,授权服务器将带重定向URL返回给我。在我的服务器中,我为此重定向URL保留了一个端点。在这个端点中,我接受请求的queryparameters,并通过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
。消息永远不会进入任何渠道。我想知道为什么会这样吗?我将添加一张图片,显示对get呼叫/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套接字服务器。因此,服务器配置似乎没有问题。我猜有一个关于http服务器的小技巧。仍在等待帮助,谢谢。
答案 0 :(得分:0)
我解决了这个问题。似乎在AuthorizationController(第一个代码部分)中,我将数据发送到websocket,我需要对数据应用json编码。
channel.sink.add(json.encode(map));