AnyEventサンプルその5
AnyEvent::Handleの扱いに苦労した。
ioやtimerのヲチャー変数のようにundefでも行けた。参照カウントが残っているとどうもよくないのかしらね。AnyEvent::JSONRPC::Liteでもweaken $handleとやっている部分がどうも今ひとつ理解できずにいたのだが、大事だよということはよくわかった。
サーバ側
use strict; use warnings; use AnyEvent; use AnyEvent::Handle; use AnyEvent::Socket; use Data::Dumper; tcp_server '127.0.0.1', 8888, sub { my ($fh) = @_ or die; my $handle = AnyEvent::Handle->new( fh => $fh, on_error => sub { shift->destroy; warn "ON_ERROR"; }, on_eof => sub { shift->destroy; warn "ON_EOF"; }, ); $handle->on_read( sub { undef $handle; warn "ON_READ"; shift->unshift_read( json => sub { my ( $handle, $request ) = @_; $handle->push_write( json => { foo => $request->{foo} . " echo!!" } ); } ); } ); }; sub _time { warn AnyEvent->now; } AE::cv->recv;
サーバ側(デッドロック?してしまうだめな例)
use strict; use warnings; use AnyEvent; use AnyEvent::Handle; use AnyEvent::Socket; use Data::Dumper; tcp_server '127.0.0.1', 8888, sub { my ($fh) = @_ or die; my $handle = AnyEvent::Handle->new( fh => $fh, on_error => sub { shift->destroy; warn "ON_ERROR"; }, on_eof => sub { shift->destroy; warn "ON_EOF"; }, ); $handle->on_read( sub { warn "ON_READ"; ## ここのundef $handleがないとダメ。 shift->unshift_read( json => sub { my ( $handle, $request ) = @_; $handle->push_write( json => { foo => $request->{foo} . " echo!!" } ); warn "WRITE"; $handle->destroy; } ); } ); }; sub _time { warn AnyEvent->now; } AE::cv->recv;
クライアント側
use strict; use warnings; use AnyEvent; use AnyEvent::Handle; use AnyEvent::Socket; use Data::Dumper; my $cv = AE::cv; tcp_connect '127.0.0.1', 8888, sub { my ($fh) = @_ or die; my $handle = AnyEvent::Handle->new( fh => $fh, on_error => sub { shift->destroy; warn "ON_ERROR"; }, on_eof => sub { shift->destroy; warn "ON_EOF"; }, ); $handle->push_write( json => { foo => 'foo' } ); $handle->push_read( json => sub { my ( $handle, $result ) = @_; $cv->send( $result->{foo} ); } ); }; print $cv->recv; print "\n";