我有一个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;
}
}
}
我发现的无限循环示例在这种情况下不适合,因为我需要使用无限循环来检查两个连接上的传入数据。
答案 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://