如何使用Dart编写一个简单的WebSocket回显应用程序

10
我一直在尝试学习足够的html、css和Dart来创建我的第一个网页,一切进展顺利,但是我不知道如何创建一个简单的页面和一个服务器端的web socket服务器,使其只是回显它。我找到的示例通常用于说明其他Dart工具,并连接到Web上的echo服务器或执行其他使其代码对新手不简单的操作。
我试图简化Seth Ladd的示例"dart-example-web-sockets-client"作为“最佳”示例。我可以接收从页面发送的内容,重新打包并认为我正在将其发送回来,但网页上绝对没有任何反应。我通过单击从Dart编辑器内运行Web服务器时返回的URL来启动页面。由于页面不是在调试器中运行的(据我所知),我在诊断错误方面受到了障碍。
这是Seth服务器的简化代码:
void handleEchoWebSocket(WebSocket webSocket) {
log.info('New WebSocket connection');

// Listen for incoming data. We expect the data to be a JSON-encoded String.
webSocket
  .map((string) => JSON.decode(string))
  .listen((json) {
    // The JSON object should contain a 'request' entry.
     var request = json['request'];
     switch (request) {
       case 'search':  
         var input = json['input'];
         log.info("Received request '$request' for '$input'");
         var response = {
           'response': request,
           'input': input,
      };
      webSocket.add(JSON.encode(response)); // can't detect page receiving this.
      log.info("Echoed request..$request $input"); // correct data
      break;

    default:
      log.warning("Invalid request: '$request'");
      }
    }, onError: (error) {
  log.warning('Bad WebSocket request');
  });
}

这个例子使用用户的输入作为两个搜索引擎的输入,将结果打包并返回到页面上进行显示,同时动态创建新的DOM元素。

我只需要一个简单的例子,可以回显提交的内容。

2个回答

14

这是一个简单的 WebSocket 客户端/服务器回显示例。消息不会显示在浏览器窗口中,但它们会在控制台窗口中打印出来。您必须分别启动 server.dart 和 main.dart。两个进程将消息打印到自己的控制台窗口中。 编辑:我添加了一个输出 div,以便在浏览器中也可以显示消息。

bin\ws_server.dart:

import "dart:convert";
import 'dart:io';
import 'package:route/server.dart' show Router;



void handleWebSocket(WebSocket webSocket) {
  // Listen for incoming data. We expect the data to be a JSON-encoded String.
  webSocket
    .map((string)=> JSON.decode(string))
    .listen((json) {
      // The JSON object should contains a 'echo' entry.
      var echo = json['echo'];
      print("Message to be echoed: $echo");
      var response='{"response": "$echo"}';
      webSocket.add(response);
    }, onError: (error) {
      print('Bad WebSocket request');
    });
}


void main() {
  int port = 9223;

  HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port).then((server) {
    print("Search server is running on "
             "'http://${server.address.address}:$port/'");
    var router = new Router(server);
    // The client will connect using a WebSocket. Upgrade requests to '/ws' and
    // forward them to 'handleWebSocket'.
    router.serve('/ws')
      .transform(new WebSocketTransformer())
      .listen(handleWebSocket);
  });
}

web\index.html:

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <title>Websocket echo</title>
  </head>
  <body>
    <p>Websocket test</p>
    <div id="output"></div>

    <script type="application/dart" src="main.dart"></script>
  </body>
</html>

web\main.dart:

library main;

import 'dart:async';
import 'dart:convert';
import 'dart:html';

class WebsocketService {

  WebSocket webSocket;

  WebsocketService() {
    connect();
  }

  void connect() {
    webSocket = new WebSocket('ws://127.0.0.1:9223/ws');
    webSocket.onOpen.first.then((_) {
      onConnected();
      sendws("Hello websocket server");
      webSocket.onClose.first.then((_) {
        print("Connection disconnected to ${webSocket.url}");
        onDisconnected();
      });
    });
    webSocket.onError.first.then((_) {
      print("Failed to connect to ${webSocket.url}. "
            "Please run bin/server.dart and try again.");
      onDisconnected();
    });
  }

  void onConnected() {
    webSocket.onMessage.listen((e) {
      onMessage(e.data);
    });
  }

  void onDisconnected() {
    print("Disconnected, trying again in 3s");
    new Timer(new Duration(seconds:3), (){
      connect();
    });
  }

  void onMessage(data) {
    var json = JSON.decode(data);
    var echoFromServer = json['response'];
    print("Received message: $echoFromServer");
    var output=querySelector('#output');
    output.text="Received message: $echoFromServer";

    new Timer(new Duration(seconds:3), (){ //Send a new message to server after 3s
      String now = new DateTime.now().toString();
      sendws("Time: $now");
    });

  }

  void sendws(String msg){
    var request = '{"echo": "$msg"}';
    print("Send message to server: $request");
    webSocket.send(request);
  }
}

void main() {
  WebsocketService ws=new WebsocketService();
}

我认为这正是我所需要的。巧合的是,你使用了“library main;”,这激励了这个新手重新阅读《Dart库之旅》,并学到了一些我之前忽略的细节。 - Nate Lockwood
@natelockwood 很高兴能帮到你,当你提出问题时,我正在研究WebSockets。 - grohjy
2
这个答案已经过时了,因为Dart包“route”已经停用。这个Stack Overflow答案有一个更好的WebSocket服务器实现:https://dev59.com/Uq7la4cB1Zd3GeqPisQ_#52591092 如果你只想测试服务器,你可以使用这个页面上基于浏览器的WebSocket客户端https://www.websocket.org/echo.html - Mark
但是main.dart部分仍然是如今人们会这样做的方式吗? - Torsten Bronger

0
你现在可以尝试使用这个包了: https://pub.dev/packages/websocket_universal 以下是一个简单的示例:
// ignore_for_file: avoid_print
import 'package:websocket_universal/websocket_universal.dart';

/// Example works with Postman Echo server
void main() async {
  /// 1. Create webSocket handler:
  final textSocketHandler = IWebSocketHandler<String, String>.createClient(
    'wss://ws.postman-echo.com/raw', // Postman echo ws server
    SocketSimpleTextProcessor(),
  );

  /// 2. Listen to webSocket messages:
  textSocketHandler.incomingMessagesStream.listen((inMsg) {
    print('> webSocket  got text message from server: "$inMsg" '
        '[ping: ${textSocketHandler.pingDelayMs}]');
  });
  textSocketHandler.outgoingMessagesStream.listen((inMsg) {
    print('> webSocket sent text message to   server: "$inMsg" '
        '[ping: ${textSocketHandler.pingDelayMs}]');
  });

  /// 3. Connect & send message:
  await textSocketHandler.connect();
  textSocketHandler.sendMessage('Hello server!');
  await Future<void>.delayed(const Duration(seconds: 4));

  // 4. Disconnect & close connection:
  await textSocketHandler.disconnect('manual disconnect');
  textSocketHandler.close();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接