Dart / Flutter WebSocket服务器/客户端无法在同一侧正常工作

时间:2020-07-02 20:18:19

标签: flutter dart websocket tcp

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服务器的小技巧。仍在等待帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。似乎在AuthorizationController(第一个代码部分)中,我将数据发送到websocket,我需要对数据应用json编码。

channel.sink.add(json.encode(map));