当前位置: 首页 > 知识库问答 >
问题:

Cro::WebSocket::Client不工作

高嘉树
2023-03-14

用"cro sub"创建了一个web套接字服务器

这名客户写道:

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

我在tcp转储中看到了来自服务器的响应代码101(交换协议),但我没有看到从客户端发送到服务器的消息。

那么,我做错了什么?

另一个问题,不应该“$connection.send”返回一个promise还是什么?如果发送时出错怎么办?

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

就这样,现在。

使现代化

按照Takao的建议,改变

$connection.send($counter)

$connection.send($counter.Str)

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

共有1个答案

幸乐湛
2023-03-14

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

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

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

因此,在调试过程中,我看到了这个错误:[TRACE(anon 1)]Cro::HTTP::ResponseParser QUIT找不到适用于此消息的正文序列化程序,正如它所说的,您发送的正文无法序列化。所以我查看了您发送的内容:$counter$counter在您的代码中是Int,因此我们需要在执行简单的$counter之前将其设置为Str。Str使您的示例有效。

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

至于你的其他问题:

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

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

服务器似乎只了解IPV6地址。。。如何让它理解IPV4地址?

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

 类似资料:
  • 我在HTTP路由中非常成功地使用了Cro HTTP身份验证/授权/会话。 然后我添加了一个路由,使用创建一个,并且我可以使用和一切工作正常。 现在我想控制对websocket的访问,所以我添加了一个参数。效果很好。现在,客户端得到了一个

  • <?php require dirname(__DIR__) . '/vendor/autoload.php'; use Yurun\Util\YurunHttp; use Yurun\Util\HttpRequest; YurunHttp::setDefaultHandler(\Yurun\Util\YurunHttp\Handler\Swoole::class); go(function(

  • Websocket-Client 是 Python 上的 Websocket 客户端。它只支持 hybi-13,且所有的 Websocket API 都支持同步。

  • 下面的客户端程序从WebSocket服务器接收消息。 它不发送任何消息。 现在,当服务器退出时(比如说,通过Ctrl C),客户机什么也看不到。 在客户机中设置CRO_TRACE=1会产生以下结果: 客户没有显示更多内容(然后我取消了它)。 所以,问题是:客户机应该如何处理这种情况? 编辑了问题,现在显示服务器代码 还有,我在Fedora 28。当我第一次取消服务器时,netstat显示 Tcpd

  • 我成功订阅了一个队列,但在发送消息时,另一个用户没有收到它 消息代理配置: 我如何发送消息 在ws-connection上创建自定义用户主体 在客户端,我连接套接字 当我连接到stomp时,我会在浏览器控制台中看到下一条消息 是此用户的实际id 我将id为1的用户和id为2的用户订阅到同一队列,当我从用户1向用户2发送消息时,第二个用户没有收到消息<我错过什么了吗?

  • 我通过web套接字发送一个文本到一个Java服务器,但不会被调用,这是我为客户端使用的函数(WebSocketTest),当我关闭服务器时,会正确调用on近函数的警报消息 这就是我在服务器上接收到的内容 这是服务器端