Raku Cro::WebSocket::客户端不';行不通

Raku Cro::WebSocket::客户端不';行不通,raku,cro,Raku,Cro,创建了一个带有“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 TIME

创建了一个带有“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”返回一个承诺还是什么?如果发送时出错怎么办

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

就这样,现在


更新

按照Takao的建议,改变

$connection.send($counter)


解决了这个问题(尽管我在另一个程序上试过了,但不是在这个程序上)。

让我们逐一解决这个问题

首先,在我看来,你的代码看起来是正确的,除了一些微小的部分

当我复制您的代码时,它确实不起作用,因此我尝试使用
cro跟踪。
而不是
cro运行。
。您可以在中找到有关该模式的信息。 另一种方法是只设置
CRO_TRACE=1
环境变量

因此,在调试期间,我看到了以下错误:

[TRACE(anon 1)]Cro::HTTP::ResponseParser退出找不到适用于此消息的正文序列化程序
正如上面所说,您发送的正文无法序列化。所以我查看了您发送的内容:
$counter
<代码>$counter在您的代码中是
Int
,因此我们需要在执行简单的
$counter.Str
之前将其设置为
Str

另外,请注意,您正在每个回复上发送一条消息,而echo服务器(您使用
cro stub
创建的默认服务器)也会为每个传入的消息发送一条回复,因此您的示例会无休止地发送消息。为了防止你可以考虑添加一个条件,在这个条件下,你将不再发送东西,但是,无论如何,它是一个测试例子,所以到你。

至于你的其他问题:

另一个问题,不应该“$connection.send”返回一个承诺还是什么

不应该,我将写一些cro的架构细节来解释它。正如您从阅读中了解到的,cro管道基本上只是一堆
cro::Transform
包装的供应品。在
Cro::Websocket::Client::Connection
内部,
send
方法只是将一个东西直接发送到整个管道的
Cro::Source
,使用一个简单的
$supplier.emit($message)
(此方法的实际实现看起来非常接近这一行)。你遇到的事情发生在管道的更深处。我相信这不是一个很好的用户体验来隐藏这种情况的例外,所以我会考虑制作一个补丁来传播异常,所以它更容易被捕获(虽然你总是可以使用调试模式)。 服务器似乎只理解IPV6地址…如何让它理解IPV4地址

我对此不确定,请提出一个新问题

$connection.send($counter.Str)