Cro::WebSocket::Client 无效

Cro::WebSocket::Client doesn't work

使用 "cro sub" 创建了一个 websocket 服务器。

写给这个客户:

use v6;
use Cro::WebSocket::Client;

constant WS-PORT = '20000';
constant WS-ADDRESS = 'localhost';
constant WS-PATH = 'chat';
constant WS-URL = 'ws://' ~ WS-ADDRESS ~ ':' ~ WS-PORT ~ '/' ~ WS-PATH;
constant TIMEOUT-TO-CONNECT = 5; # seconds

my $timeout;
my $connection-attempt;

await Promise.anyof(
  $connection-attempt = Cro::WebSocket::Client.connect(WS-URL),
  $timeout = Promise.in(TIMEOUT-TO-CONNECT));

if $timeout.status == Kept
{
  say "* could not connect to server in ', TIMEOUT-TO-CONNECT, ' seconds";
  exit 1;
}

if $connection-attempt.status != Kept
{
  say "* error ", $connection-attempt.cause,
    " when trying to connect to server";
  exit 1;
}

my $connection = $connection-attempt.result;
my $peer = WS-ADDRESS ~ ':' ~ WS-PORT;
say '* connected with ', $peer;

my $counter = 0;

my $message-supplier = Supplier::Preserving.new;
my $has-message-to-send = $message-supplier.Supply;
$message-supplier.emit(1);

react
{
  whenever $has-message-to-send
  {
    $counter++;
    $connection.send($counter);
    say "* ok, sent message ", $counter, " to server"; 
  }

  whenever $connection.messages -> $reply
  {
    say '* received reply=[' ~ $reply ~ '] from server';
    $message-supplier.emit(1);
  }

} # react

我使用 tcpdump 看到服务器的响应代码 101(切换协议),但我没有看到从客户端发送到服务器的消息。

那么,我做错了什么?

另一个问题,“$connection.send”return 不应该是 Promise 之类的吗?发送时出错怎么办?

还有另一个问题:服务器似乎只理解 IPV6 地址...如何让它理解 IPV4 地址?

到此为止。


更新

按照 Takao 的建议,更改

$connection.send($counter)

$connection.send($counter.Str)

解决了问题(虽然我在另一个程序上尝试过,不是这个)。

让我们一步步解决这个问题。

首先,你的代码在我看来是正确的,除了一些小的地方。

当我复制你的代码时,它确实不起作用,所以我用cro trace .而不是cro run .试了一下。您可以在 official docs 中找到有关该模式的信息。 另一种方法是设置 CRO_TRACE=1 环境变量。

因此在调试期间我看到了这个错误: [TRACE(anon 1)] Cro::HTTP::ResponseParser QUIT No applicable body serializer could be found for this message 正如它所说,您发送的正文无法序列化。所以我查看了您要发送的内容:$counter$counter 在你的代码中是 Int,所以我们需要在 Str 之前,做简单的 $counter.Str 让你的例子工作。

另外,请注意,您在每次回复时都发送一条消息,回显服务器(您使用 cro stub 创建的默认服务器)也会为每条传入消息发送回复,因此您的示例会无休止地发送消息。为了防止你可以考虑添加一个条件,在这种情况下你将不再发送东西,但是好吧,这无论如何是一个测试示例,所以由你决定。

关于您的其他问题:

Another question, shoudn't "$connection.send" return a Promise or something?

应该不会吧,接下来我会把cro的架构细节写出来解释一下。正如您可能通过阅读 docs 了解到的那样,cro 管道基本上只是一堆 Cro::Transform 包装的供应品。在 Cro::Websocket::Client::Connection 内部,send 方法只是将一个东西直接发送到整个管道的 Cro::Source 中,简单的 $supplier.emit($message) 你不会出错(这个方法的真正实现看起来非常接近这条线)。您遇到的事情发生在管道的更深处。我确信隐​​藏这种情况的异常不是一个好的用户体验,所以我会考虑制作一个补丁来传播异常,这样它会更容易捕获(尽管你总是可以使用调试模式)。

it seems the server only understands IPV6 addresses...how to make it understand IPV4 addresses ?

我不太确定,请打开一个新问题。