Perl,无限循环中的websocket

时间:2016-12-12 23:18:47

标签: perl loops websocket client infinite

我有一个perl脚本,作为本地程序和外部交互式网站之间的“中间人”。

问题是外部网站从普通tcp连接迁移到websocket连接。

当服务器使用tcp时,初始连接后,客户端(脚本)和服务器(外部网站)将通过握手,然后脚本将发送用户名和密码,服务器将最终响应一些加密密钥,然后脚本将进入无限循环并等待来自两个连接的数据,然后处理该数据和" print"根据需要回到连接。

我能够使用Mojo :: UserAgent以及protocol :: websocket建立与服务器的websocket连接,通过握手和其他信息交换(用户名,密码等),但我有不能(或更好地说:我不知道如何)去"扔"通过IO :: Select将websocket连接到无限循环中(我想使用IO :: Select的原因是因为这样做需要对脚本进行最少的更改,但其他建议肯定是受欢迎的。)

脚本的相关部分如下:

# Creating connection for local program
$lsn=new IO::Socket::INET(
    Proto => 'tcp',
    LocalPort => 6000,
    Listen => 1,
);
unless(defined $lsn){
    print"$0: $!\n";
    exit 1;
}
print"Waiting for local program connection on port 6000\n";
$server=$lsn->accept;
$lsn->close;
unless(defined $server){
    print "$0: Unable to accept incoming connection: $!\n";
    exit 1;
    }
# At this point, the script is waiting for a connection from
# the local program on port 6000
printf"Connection accepted from %s\n",$server->peerhost;
select $server;
binmode $server;
$stdin=$server;
(select)->autoflush(1);
# Creating connection for external website
$net=new IO::Socket::INET(
    Proto => 'tcp',
    PeerAddr => $yog,
    PeerPort => $yserverport,
);

unless(defined($net)){
    print "Can't connect!\n";
    exit 1;
}
$net->autoflush(1);
####################################
# Here the script and server will  #
# exchange information few times   #
####################################
my $sel=new IO::Select($stdin,$net);
$net->autoflush(0);
while (1){
    foreach my $i($sel->can_read(0.05)){
        if($i==$net){
            &dosomething;
            $net->flush;
        }
        else{
            &dosomething2;
            $net->flush;
        }
    }   
}

我发现的无限循环示例在这种情况下不适合,因为我需要使用无限循环来检查两个连接上的传入数据。

1 个答案:

答案 0 :(得分:1)

WebSockets需要的不仅仅是简单的IO套接字。它们需要握手和数据框架。我会检查W3C WebSocket API,然后研究使用perl模块(Net::WebSocket::Server)来完成繁重的工作。此外,webSockets仅适用于使用SSL的chrome浏览器,因此如果对交叉兼容性感兴趣,请使用带有IO :: Socket :: SSL的Net :: WebSocket :: Server,这里是SSL的工作示例:

#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::SSL;
use Net::WebSocket::Server;

my $ssl_server = IO::Socket::SSL->new(
      Listen        => 5,
      LocalPort     => 4000,
      Proto         => 'tcp',
      SSL_cert_file => '/var/ssl/cert.crt',
      SSL_key_file  => '/var/ssl/cert.key',
    ) or die "failed to listen: $!";

my $port = 6000;
my $origin = 'https://YOURDOMAIN.com';

Net::WebSocket::Server->new(
    listen => $ssl_server,

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

            handshake => sub {
                        my ($conn, $handshake) = @_;
                        $conn->disconnect() unless $handshake->req->origin eq $origin;
                    },
                    utf8 => sub {

            my ($conn, $msg) = @_;
            my $MyIP = $conn->ip();
            my $MyPORT = $conn->port();
             $_->send_utf8($msg) for( $serv->connections() );
                },
    );
    },
)->start;

如果您不关心Chrome或SSL,这是一个有效的非SSL示例,(它需要使用严格并使用警告):

#!/usr/bin/perl

use Net::WebSocket::Server;

my $port = 6000;

Net::WebSocket::Server->new(
    listen => $port,
    on_connect => sub {
        my ($serv, $conn) = @_;
        $conn->on(
            utf8 => sub {
        my ($conn, $msg) = @_;
                $_->send_utf8($msg) for( $serv->connections() );
            },
        );
    },
)->start;

此外,如果您决定使用SSL版本,请务必将客户端从ws://更新为wss://