【问题标题】:How to write a client program for Net::WebSocket::Server program?如何为 Net::WebSocket::Server 程序编写客户端程序?
【发布时间】:2021-06-27 13:12:34
【问题描述】:

我有一个监听 9000 端口的服务器程序。但是我找不到一种方法来为连接 9000 端口的服务器的服务器编写客户端程序。这是服务器程序的主要部分:

use strict;
use warnings;

use Net::WebSocket::Server;
    
my $port = "9000";
my $msg_count = 0;

print "starting server on $port \n\n";

my $count = 2400;

Net::WebSocket::Server->new(
    listen => $port,
    silence_max => 5,

    tick_period => 300,
    on_tick => sub {
        my ($serv) = @_;    
        print "connections >> " . $serv->connections . "\n";    
        print $_->ip() for( $serv->connections() ); print "\n";
        print $_->port() for( $serv->connections() ); print "\n\n";
        $count++;    
    },

    on_connect => sub {
        my ($serv, $conn) = @_;
        $conn->on(   

        handshake => sub {
                my ($conn, $handshake) = @_;
                my $tmp = $handshake->req->origin;
                print "here ... $tmp \n\n";    
        },

            utf8 => sub {
                my ($conn, $msg) = @_;
                my $IP = $conn->ip();
                my $PORT = $conn->port();
                my $SERVER = $conn->server();
                my $SOCKET = $conn->socket();
                my $str = Dumper $SOCKET;

我搜索了互联网,听起来我可以理解的是以下客户端程序:

use strict;
use warnings;
use IO::Socket::SSL;

my $cl=IO::Socket::SSL->new("http://localhost:9000") or die "error=$!, ssl_error=$SSL_ERROR"; 
if($cl) {
    $cl->connect_SSL or die $@;
    # Something about certificates?
    $cl->syswrite("Command");
    close($cl);
}

但它不起作用。客户端程序产生的错误如下:

Expected 'PeerService' at client2.pl line 5.

我是 Socket 编程的新手,目前了解 Perl 中的 websockets 编程。

注意:我在windows平台上。

我运行了建议的示例代码 https://stackoverflow.com/questions/37318581/simple-perl-websocket-client. 它给出了错误“不能在 C:/Strawberry/perl/site/lib/Protocol/WebSocket/Client.pm 第 103 行使用未定义的值作为子例程引用。” :

use strict;
use warnings;
use Protocol::WebSocket::Client;

my $client = Protocol::WebSocket::Client->new(url => 'ws://localhost:9000') or die "$!";
my $reply = "Free\n";
# Sends a correct handshake header
$client->connect or die "$!";

# Register on connect handler
$client->on(
    connect => sub {
        $client->write('hi there');
    }
) or die "$!";

# Parses incoming data and on every frame calls on_read
$client->read($reply);
print "$reply\n";

# Sends correct close header
$client->disconnect;

【问题讨论】:

  • 1. Websocket 既不是普通的 TCP 套接字也不是普通的 SSL 套接字。 2. IO::Socket::SSL 使用完全关闭,请参阅文档了解如何使用它。简而言之:它没有将 URL 作为目标。 3.有easy to find examples for websocket client in perl。 4.Simple Perl websocket client可能重复
  • 堆栈后代码的示例给了我以下错误“不能在 C:/Strawberry/perl/site/lib/Protocol/WebSocket/Client.pm 行使用未定义的值作为子例程引用103.”
  • 您的服务器没有使用 SSL(您需要为 SSL 通信提供证书),另一方面您尝试在客户端使用 SSL 通信——您希望他们如何相互理解?也许在您的问题中,您应该首先说明您的目标——我想在端口# 上工作的服务器和网络客户端之间建立安全/不安全的通信,以传递以下类型的信息。我想出了以下 server 代码,但无法通过以下 client 达到预期的结果。
  • (上一条评论的继续)我已经测试了与网络浏览器和nc 的通信,确认服务器正常工作。

标签: perl websocket client-server


【解决方案1】:

请调查WebSocket ServerClient 的以下演示代码 sn-ps。

注意:请不要忘记更改代码以匹配您的服务器来源(IP 地址和端口)

use strict;
use warnings;
use feature 'say';

use Net::WebSocket::Server;

my $origin = 'http://192.168.1.160:8080';  # server origin
my $port = 8080;

$| = 1;

say "Starting server on $port";

Net::WebSocket::Server->new(
    listen => $port,
    tick_period => 60,
    on_tick => sub {
        my ($serv) = @_;
        my $stamp = 'Server time: ' . scalar localtime;
        $_->send_utf8($stamp) for $serv->connections;
    },
    on_connect => sub {
        my ($serv, $conn) = @_;
        $conn->on(
            handshake => sub {
                my ($conn, $handshake) = @_;
                $conn->disconnect() unless $handshake->req->origin eq $origin;
            },
            ready => sub {
                my ($conn) = @_;
                say "Client: connect IP $conn->{ip} PORT $conn->{port}";
                my $msg = 'Connected server time is ' . scalar localtime . "\n";
                $_->send_utf8($msg) for $conn->server->connections;
            },
            utf8 => sub {
                my ($conn, $msg) = @_;
                say "Client message: $conn->{ip} $msg";
                $_->send_utf8('Server reply: ' . $msg)
                        for $conn->server->connections;
                $conn->disconnect() if $msg eq 'exit';
            },
            binary => sub {
                my ($conn, $msg) = @_;
                $_->send_binary($msg) for $conn->server->connections;
            },
            pong => sub {
                my ($conn, $msg) = @_;
                $_->send_utf8($msg) for $conn->server->connections;
            },
            disconnect => sub {
                my ($conn, $code, $reason) = @_;
                say "Client: disconnect IP $conn->{ip} PORT $conn->{port}";
            },
        );
    },
)->start;

客户

use strict;
use warnings;
use feature 'say';

use IO::Async::Loop;
use Net::Async::WebSocket::Client;

my $HOST = '192.168.1.160';
my $PORT = 8080;

my $loop = IO::Async::Loop->new;

my $client = Net::Async::WebSocket::Client->new(
   on_text_frame => sub {
      my ( $self, $frame ) = @_;
      say $frame;
   },
);

my $input = IO::Async::Stream->new_for_stdin(
    on_read => sub {
        my ( $self, $buffref, $eof ) = @_;

        my $msg;

        $msg = $1 while $$buffref =~ s/^(.*)\n//;

        $client->send_text_frame( $msg );

        $loop->loop_stop if $msg eq 'exit';

        return 0;
    },
);

$loop->add( $client );
$loop->add( $input  );

$client->connect(
   url => "ws://$HOST:$PORT/"
)->then( sub {
    say 'Successfully connected to server';
    $client->send_text_frame( scalar localtime );
})->get;

$loop->run;

say 'Bye, until next time';

exit 0;

参考资料:

【讨论】:

  • 我更改了上面的代码 sn-ps 以反映我的服务器和端口来源并运行代码。两个 sn-ps 都成功执行,但是客户端进程在与服务器成功连接后不显示任何输出。我终止了客户端代码,服务器显示客户端断开连接的消息。我们可以修改代码以反映成功连接后服务器和客户端之间的消息交换吗?
  • 服务器/客户端进程之间没有发生消息交换。
  • 您需要进行网络故障排除,为简单起见尝试打开防火墙进行测试,看看它是否会改变输出。在我的情况下,我在同一台计算机上使用 Ubuntu 20.04 作为服务器和客户端,两者都运行良好,服务器发送“on_tick”消息至少一个小时。
  • 我也在同一台计算机上使用服务器和客户端,但仍然没有发生消息交换。
  • 我在 Windows 10 上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-24
  • 1970-01-01
  • 2018-03-28
相关资源
最近更新 更多