Cro :: WebSocket :: Client不起作用

时间:2018-07-18 14:51:44

标签: perl6 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 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”是否应返回Promise之类的东西?如果发送时出现错误怎么办?

还有另一个问题:看来服务器仅理解IPV6地址...如何使其理解IPV4地址?

仅此而已。


更新

根据高尾的建议,进行更改

$connection.send($counter)

$connection.send($counter.Str)

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

1 个答案:

答案 0 :(得分:6)

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

首先,您的代码对我来说是正确的,除了一些小细节。

当我复制您的代码时,它确实不起作用,因此我使用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。您代码中的$counterInt,因此我们需要先做Str,然后做简单的$counter.Str才能使示例工作。

此外,请注意,您将在每个答复中发送一条消息,而echo服务器(使用cro stub创建的默认服务器)也会为每条传入消息发送一条答复,因此您的示例将不断发送消息。为了防止这种情况,您可以考虑添加一个条件,在该条件下您将不再发送邮件,但是无论如何,这都是一个测试示例,具体取决于您。

关于您的其他问题:

  

另一个问题,“ $ connection.send”是否应返回Promise或其他内容?

不应该,我将写出一些cro的体系结构详细信息来进行解释。正如您从阅读docs可能会了解到的那样,cro管道基本上只是一堆Cro::Transform包装的用品。在Cro::Websocket::Client::Connection内部,send方法只是将事物直接发送到整个管道的Cro::Source中,使用简单的$supplier.emit($message)就不会出错(该方法的实际实现看起来很简单非常接近此线)。您碰到的东西发生在管道中。我确信隐​​藏此类情况的异常不是很好的用户体验,因此我将考虑制作一个补丁来传播异常,因此更容易捕获(尽管您始终可以使用调试模式)。

  

服务器似乎只了解IPV6地址...如何使其了解IPV4地址?

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