gpt4 book ai didi

perl - Mojolicious 重用先前建立的连接

转载 作者:行者123 更新时间:2023-12-04 20:31:27 26 4
gpt4 key购买 nike

我正在尝试重用以前建立的 websocket 连接来避免 websocket 握手。我发现可以使用 build_websocket_tx 构建自定义 websocket 事务(更多详细信息 here ),并且每个 websocket 连接都有一个连接标识符,可以使用 connection 检索。 Mojo::Transaction 中定义的子程序(更多详情 here)。我可以以某种方式将这两者结合起来重新使用连接吗?还有另一种方法吗?

PS:Websocket 连接应该是一致的和可重用的。但是 Mojolicoious 没有为 websocket 连接提供任何这样的选项。

编辑

没有连接重用的示例代码。

#!/usr/bin/perl

use strict;
use warnings;

use Mojo::UserAgent;
use JSON qw |encode_json|;

my $ua = Mojo::UserAgent->new;
my $url = "wss://trello.com/1/Session/socket";

$| = 1;

sub _connect {
my $req = {
type => "ping",
reqid=> 0
};
$ua->websocket(
$url => sub {
my ($ua, $tx) = @_;

die "error: ", $tx->res->error->{message}, "\n" if $tx->res->error;
die 'Not a websocket connection' unless $tx->is_websocket;

# Connection established.
$tx->on(
message => sub {
my ($tx, $msg) = @_;
print "$msg\n";
$tx->closed; #Close connection
});
$tx->send(encode_json($req));
});
}

sub reuse_conn {
# Re use connection
}

_connect();

Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

最佳答案

预备:运行带有调试信息的 Mojolicious 客户端脚本:

MOJO_EVENTEMITTER_DEBUG=1 MOJO_USERAGENT_DEBUG=1 perl mua.pl

在 7.43 版中, Mojo::UserAgentbuilt-in connection pooling但是 specifically refuses to use it for WebSockets .这很可能是因为正如您所说,WebSockets 是有状态的,如果 UserAgent 盲目地重用连接,那可能会造成困惑。但是,如果您的应用程序知道如何安全地重用它们,那就是另一回事了。

这个问题最近出现在 Mojolicious 的 IRC channel ,和 sri, the author, said :
16:28   sri     mohawk: some frameworks like phoenix have their own higher level protocol on top of websockets to multiplex multiple channels https://hexdocs.pm/phoenix/channels.html16:28       sounds like that's what you want16:28       mojolicious should have something like that, but doesn't yet[...]16:42   sri     it's not hard to build on top of mojolicious, but for now you have to do that yourself16:42       ultimately i'd hope for us to have it in core, without the message bus part16:43       but channel management and routing[...]16:50   jberger mohawk I did write Mojolicious::Plugin::Multiplex which might help16:51       For an example of a higher level tool

I acknowledge OP said:

The only way I was able to reuse connection was by storing the transaction object and use it in subsequent calls.

However, as the code currently is, it appears this is the only way. This code demonstrates how to make, maintain, and use your own connection pool:

#!/usr/bin/perl

use strict;
use warnings;
use Mojo::UserAgent;
use Time::HiRes qw(time);
$| = 1;
my $REQ = {
type => "ping",
reqid => 0,
};
my $URL = "wss://trello.com/1/Session/socket";
my $SECONDS = 2;
my $POOL_SIZE = 5;

my $ua = Mojo::UserAgent->new;
my @pool;

sub make_conn {
my ($ua, $url, $pool) = @_;
$ua->websocket($URL => sub {
my (undef, $tx) = @_;
die "error: ", $tx->res->error->{message}, "\n" if $tx->res->error;
die 'Not a websocket connection' unless $tx->is_websocket;
push @$pool, $tx;
});
}

# pool gets pushed onto, shifted off, so using recently-used connection
sub send_message {
my ($pool, $request, $start) = @_;
my $tx = shift @$pool;
die "got bad connection" unless $tx; # error checking needs improving
$tx->once(message => sub {
my (undef, $msg) = @_;
print "got back: $msg\n";
print "took: ", time - $start, "\n";
push @$pool, $tx;
});
$tx->send({json => $request});
}

make_conn($ua, $URL, \@pool) for (1..5); # establish pool

# every 2 secs, send a message
my $timer_cb;
$timer_cb = sub {
my $loop = shift;
print "every $SECONDS\n";
send_message(\@pool, $REQ, time);
$loop->timer($SECONDS => $timer_cb);
};
Mojo::IOLoop->timer($SECONDS => $timer_cb);

Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

在高层次上,它的工作方式如下:
  • 在池中建立 5 个连接
  • send_message使用该池中最近最少使用的连接
  • 每两秒发送一条消息,注册一次“on message”回调来处理响应

  • 为简单起见,当它从池中获取连接时,它不会检查连接是否仍在工作,而是依靠前两秒的延迟来初始化所有 5 个连接。
    time的使用调用演示了使用此池的速度增益。您提供的代码需要(在我的系统上)大约 300 毫秒来启动连接,然后发送和接收。使用池,大约需要 120 毫秒。

    关于perl - Mojolicious 重用先前建立的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45497182/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com