您好我有一个POE TCP服务器,它需要处理多个客户端。新客户端连接并请求服务器“开始发送数据”,服务器将开始发送数据,当客户端请求服务器“停止发送数据”时服务器将停止发送数据。这应该发生在多个客户端。我尝试过但它只处理一个客户端。以下是代码,请帮我解决这个问题?
use warnings;
use strict;
use POE;
use POE::Component::Server::TCP;
use Data::Dumper;
POE::Component::Server::TCP->new(
Alias => "server",
Port => 2000,
ClientFilter => 'POE::Filter::Stream',
ClientArgs => [
$ARGV[0]
],
Started => sub {
my ($session, $heap) = @_[SESSION, HEAP];
print STDERR "Server started\n";
},
ClientConnected => sub {
my($session, $kernel, $heap) = @_[SESSION, KERNEL, HEAP];
$kernel->alias_set('Downloader');
$heap->{current_state} = "waiting for command";
$heap->{START} = 0;
$heap->{STOP} = 0;
$heap->{isStopPending} = 0;
$heap->{sessionID} = $_[SESSION]->ID;
},
ClientInput => sub {
my ($heap, $kernel, $session, $input) = @_[HEAP, KERNEL, SESSION, ARG0];
$heap->{input} .= $input;
process_data ($heap,$session,$kernel);
},
InlineStates => {
StartSending => sub {
my ($heap, $kernel, $session) = @_[HEAP, KERNEL, SESSION];
$kernel->post('Downloader', 'OnSending');
},
OnSending => sub {
my ($heap, $kernel, $session) = @_[HEAP, KERNEL, SESSION];
if ($heap->{isStopPending} != 0 ) {
$heap->{isStopPending} = 0;
print STDERR "Stopped to session $heap->{sessionID}...\n";
return;
}else {
print STDERR "Sending to SessionID: $heap->{sessionID}\n";
read_file ($heap);
$heap->{client}->put($heap->{data});
$heap->{data} = '';
$kernel->alarm(OnSending=> time() + 1, 0);
}
},
StopWasRequested => sub {
my ($heap, $kernel, $session) = @_[HEAP, KERNEL, SESSION];
$heap->{isStopPending} = 1;
print STDERR "Stop was requested\n";
},
},
);
sub process_data {
my ($heap, $session, $kernel) = @_;
if ($heap->{current_state} eq "waiting for command") {
process_Command ($heap);
if ($heap->{command} eq "START") {
$heap->{current_state} = "waiting for command";
Start ($heap, $kernel, $session);
} elsif ($heap->{command} eq "STOP") {
$heap->{current_state} = "waiting for command";
Stop ($heap, $kernel, $session);
}
}
return;
}
sub process_Command {
my ($heap) = @_;
my $input = $heap->{input};
my $length = length($input);
$input =~ s/^(.{$length})//;
$heap->{input} = $input;
$heap->{command} = $1;
return;
}
sub Start {
my ($heap, $kernel, $session) = @_;
return if ($heap->{START} == 1);
$heap->{START} = 1;
$heap->{STOP} = 0;
$kernel->yield('StartSending');
}
sub Stop {
my ($heap, $kernel, $session) = @_;
$heap->{STOP} = 1;
$heap->{START} = 0;
print STDERR "Stop...\n";
$kernel->post($heap->{sessionID}=>'StopWasRequested');
}
sub read_file {
my ($heap) = @_;
my $filesize = -s "0001.out";
open (RF, "<0001.out") or die "could not open file";
binmode (RF);
read (RF, my $data, $filesize);
close (RF);
$heap->{data} = $data;
return;
}
$poe_kernel->run();
exit 0;
答案 0 :(得分:0)
在ClientConnected回调中,$kernel->alias_set('Downloader');
语句适用于第一个连接客户端(会话),后续客户端(会话)不应设置相同的别名“Downloader”。在InsliStates的'StartSending'回调中,post destination是'Downloader',以便服务器将数据发送到第一个连接客户端。要将数据发送到多个客户端,请使用SESSION_ID作为目标,而不是ALIAS,在本例中为“Downloader”。所以替换:
$kernel->post('Downloader', 'OnSending');
通过
$kernel->post($_[SESSION]->ID=>'OnSending');
在Inlinestates的“StartSending”回调中。所以现在工作正常。