Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

piped client-server communication is now an option. run ./examples/mi…

…necrap.pl to try. Server does not shut down automatically (has to be killed) for now.
  • Loading branch information...
commit ea6cd639237355b441e6ccc71da85397236d6bdd 1 parent dfb4718
@zpmorgan authored
View
2  bin/construder_client
@@ -1,4 +1,4 @@
-#!/opt/perl/bin/perl
+#!/usr/bin/env perl
use common::sense;
use Games::VoxEngine;
use Games::VoxEngine::Logging;
View
2  bin/construder_server
@@ -1,4 +1,4 @@
-#!/opt/perl/bin/perl
+#!/usr/bin/env perl
use common::sense;
use AnyEvent;
use Games::VoxEngine;
View
43 bin/minecrap_client.pl
@@ -1,43 +0,0 @@
-#!/usr/bin/env perl
-use common::sense;
-use Games::VoxEngine;
-use Games::VoxEngine::Logging;
-use Games::VoxEngine::Client;
-use Getopt::Long;
-
-my $spawn_server = 0;
-my $login_name;
-GetOptions ('spawn!' => \$spawn_server,
- 'name' => \$login_name,
-);
-
-if ($spawn_server){
- if (fork()==0){
-
- exec('perl bin/construder_server');
- }
- sleep(5);
-}
-
-
-#vox_enable_log_categories ('all');
-vox_enable_log_categories ('info', 'error', 'warn', 'chat');
-
-Games::VoxEngine::Debug::init ("client");
-
-our $game = eval { Games::VoxEngine::Client->new (auto_login => $login_name) };
-if ($@) {
- vox_log (error => "Couldn't initialized client: %s", $@);
- exit 1;
-}
-
-our $in_ex; #does $in_ex do anything?
-$game->set_exception_cb (sub {
- my ($ex, $ev) = @_;
- return if $in_ex;
- local $in_ex = 1;
- vox_log (error => "exception in client (%s): %s", $ev, $ex);
- $game->{front}->msg ("Fatal Error: Exception in client caught: $ev: $ex");
-});
-
-$game->start;
View
26 examples/minecrap.pl
@@ -8,7 +8,7 @@
use IO::Pipe;
use AnyEvent;
-vox_enable_log_categories ('info', 'error', 'warn', 'chat');
+vox_enable_log_categories ('network', 'info', 'error', 'warn', 'chat');
my $spawn_server = 1;
my $login_name = 'foo';
@@ -17,8 +17,8 @@
);
if ($spawn_server){
- my $server_to_client = IO::Pipe->new();
- my $client_to_server = IO::Pipe->new();
+ my ($client_from_server, $server_to_client) = AnyEvent::Util::portable_pipe();
+ my ($server_from_client, $client_to_server) = AnyEvent::Util::portable_pipe();
if (fork()==0){
#run server.
@@ -26,10 +26,9 @@
Games::VoxEngine::Debug::init ("server");
my $server = Games::VoxEngine::Server->new(
- pipe_to_client => $server_to_client,
- pipe_from_client => $client_to_server,
- # log_categories => ['info', 'error', 'warn'],
- # log_file => '/tmp/minecrap_server.log',
+ #pipe_to_client => $server_to_client,
+ #pipe_from_client => $server_from_client,
+ run_locally => [$server_from_client, $server_to_client],
temporary => 1,
);
$server->listen;
@@ -41,12 +40,11 @@
#run client.
my $client = eval { Games::VoxEngine::Client->new (
auto_login => $login_name,
- pipe_from_server => $server_to_client,
- pipe_to_server => $client_to_server,
- # log_categories => ['info', 'error', 'warn'],
- # log_file => '/tmp/minecrap_client.log',
- host => 'localhost',
- port => 9364,
+ #pipe_to_server => $client_to_server,
+ #pipe_from_server => $client_from_server,
+ run_locally => [$client_from_server, $client_to_server],
+ #host => 'localhost',
+ #port => 9364,
) };
if ($@) {
vox_log (error => "Couldn't initialize client: %s", $@);
@@ -58,7 +56,7 @@
vox_log (error => "exception in client (%s): %s", $ev, $ex);
$client->{front}->msg ("Fatal Error: Exception in client caught: $ev: $ex");
});
- sleep(5);
+ #sleep(5);
$client->start;
View
101 lib/Games/VoxEngine/Client.pm
@@ -53,14 +53,12 @@ sub _build_event_handler{
$EH->init_object_events;
return $EH;
}
-has 'pipe_to_server' => (
+has run_locally => (
is => 'ro',
- isa => 'IO::Pipe',
-);
-has 'pipe_from_server' => (
- is => 'ro',
- isa => 'IO::Pipe',
+ isa => 'ArrayRef',
);
+sub pipe_from_server { shift()->run_locally()->[0] }
+sub pipe_to_server { shift()->run_locally()->[1] }
has 'port' => (
isa => 'Int',
@@ -73,7 +71,14 @@ has 'host' => (
is => 'ro',
default => 'localhost',
);
-
+has srv_in => (
+ is => 'rw',
+ isa => 'AnyEvent::Handle',
+);
+has srv_out => (
+ is => 'rw',
+ isa => 'AnyEvent::Handle',
+);
sub BUILD {
my $self = shift;
@@ -142,6 +147,11 @@ sub BUILD {
return $self
}
+sub is_connected{
+ my $self = shift;
+ return ( $self->srv_in() && $self->srv_out() );
+}
+
sub start {
my ($self) = @_;
@@ -150,12 +160,44 @@ sub start {
$c->recv;
}
-sub reconnect {
+sub connect {
my ($self) = @_;
- $self->connect ($self->host, $self->port);
+ if ($self->run_locally){
+ $self->piped_connect();
+ }
+ else {
+ $self->socket_connect ($self->host, $self->port);
+ }
}
-sub connect {
+sub piped_connect{
+ my $self = shift;
+
+ vox_log (debug => "connecting to piped server");
+
+ my $hdl_in = AnyEvent::Handle->new(
+ fh => $self->pipe_from_server(),
+ on_error => sub {
+ my ($hdl, $fatal, $msg) = @_;
+ $hdl->destroy;
+ $self->disconnected;
+ },
+ );
+ my $hdl_out = AnyEvent::Handle->new(
+ fh => $self->pipe_to_server(),
+ on_error => sub {
+ my ($hdl, $fatal, $msg) = @_;
+ $hdl->destroy;
+ $self->disconnected;
+ },
+ );
+ $self->{srv_in} = $hdl_in;
+ $self->{srv_out} = $hdl_out;
+ $self->handle_protocol;
+ $self->connected;
+}
+
+sub socket_connect {
my ($self, $host, $port) = @_;
vox_log (debug => "connecting to server %s at port %d", $host, $port);
@@ -166,7 +208,7 @@ sub connect {
unless ($fh) {
vox_log (error => "Couldn't connect to server %s at port %d: %s", $host, $port, $!);
$self->{front}->msg ("Couldn't connect to server: $!");
- $self->{recon} = AE::timer 5, 0, sub { $self->reconnect; };
+ $self->{recon} = AE::timer 5, 0, sub { $self->connect; };
return;
}
@@ -178,8 +220,9 @@ sub connect {
$self->disconnected;
}
);
-
- $self->{srv} = $hdl;
+ # tcp is bidirectional. Same handle for both
+ $self->{srv_in} = $hdl;
+ $self->{srv_out} = $hdl;
$self->handle_protocol;
$self->connected;
};
@@ -188,7 +231,7 @@ sub connect {
sub handle_protocol {
my ($self) = @_;
- $self->{srv}->push_read (packstring => "N", sub {
+ $self->srv_in->push_read (packstring => "N", sub {
my ($handle, $string) = @_;
$self->handle_packet (data2packet ($string));
$self->handle_protocol;
@@ -197,16 +240,21 @@ sub handle_protocol {
sub send_server {
my ($self, $hdr, $body) = @_;
- if ($self->{srv}) {
- $self->{srv}->push_write (packstring => "N", packet2data ($hdr, $body));
+ if ($self->is_connected()) {
vox_log (network => "send[%d]> %s: %s", length ($body), $hdr->{cmd}, join (',', keys %$hdr));
+ $self->srv_out->push_write (packstring => "N", packet2data ($hdr, $body));
}
}
sub connected {
my ($self) = @_;
$self->{front}->msg ("Connected to Server!");
- vox_log (info => "connected to server %s on port %d", $self->host, $self->port);
+ if ($self->run_locally){
+ vox_log (info => "connected to piped server.");
+ } else {
+ vox_log (info => "connected to server %s on port %d", $self->host, $self->port);
+ }
+
$self->send_server ({ cmd => 'hello', version => "Games::VoxEngine::Client 0.1" });
}
@@ -327,11 +375,20 @@ sub handle_packet {
sub disconnected {
my ($self) = @_;
- delete $self->{srv};
- $self->{front}->msg ("Disconnected from server!");
- $self->{front}->clear_chunks;
- $self->{recon} = AE::timer 5, 0, sub { $self->reconnect; };
- vox_log (info => "disconnected from server");
+ if($self->run_locally){
+ #local server shut down. so exit?
+ $self->_cv->send();
+ vox_log (info => "disconnected from local server");
+ }
+ else{
+ #try to reconnect.
+ delete $self->{srv_in};
+ delete $self->{srv_out};
+ $self->{front}->msg ("Disconnected from server!");
+ $self->{front}->clear_chunks;
+ $self->{recon} = AE::timer 5, 0, sub { $self->connect; };
+ vox_log (info => "disconnected from server");
+ }
}
=back
View
65 lib/Games/VoxEngine/Server.pm
@@ -18,7 +18,6 @@ package Games::VoxEngine::Server;
#use base qw/Object::Event/;
use Mouse;
-
use AnyEvent;
use AnyEvent::Handle;
use AnyEvent::Socket;
@@ -55,14 +54,12 @@ has 'temporary' => (
isa => 'Bool',
default => 0,
);
-has 'pipe_to_client' => (
- is => 'ro',
- isa => 'IO::Pipe',
-);
-has 'pipe_from_client' => (
+has run_locally => (
is => 'ro',
- isa => 'IO::Pipe',
+ isa => 'ArrayRef',
);
+sub pipe_from_client{ shift()->run_locally()->[0] }
+sub pipe_to_client{ shift()->run_locally()->[1] }
has 'port' => (
isa => 'Int',
@@ -84,7 +81,6 @@ Games::VoxEngine::Server - Server side networking and player management
=cut
our $RES;
-our $SHELL;
sub BUILD {
my ($self) = @_;
@@ -112,8 +108,47 @@ sub BUILD {
sub listen {
my ($self) = @_;
-
+
+ if ($self->run_locally){
+ #use pipes for communication
+ $self->pipe_listen();
+ }
+ else{
+ $self->tcp_listen();
+ }
#AnyEvent won't stop until $self->_cv->send().
+ $self->_cv->recv();
+};
+
+#deal with just one client, with a pipe.
+sub pipe_listen{
+ my $self = shift;
+ my $cid = "piper42";
+ my $hdl_in = AnyEvent::Handle->new(
+ fh => $self->pipe_from_client,
+ on_error => sub {
+ my ($hdl, $fatal, $msg) = @_;
+ $hdl->destroy;
+ $self->client_disconnected ($cid, "error: $msg");
+ },
+ );
+ my $hdl_out = AnyEvent::Handle->new(
+ fh => $self->pipe_to_client,
+ on_error => sub {
+ my ($hdl, $fatal, $msg) = @_;
+ $hdl->destroy;
+ $self->client_disconnected ($cid, "error: $msg");
+ },
+ );
+ $self->{clients}->{$cid}{in} = $hdl_in;
+ $self->{clients}->{$cid}{out} = $hdl_out;
+ $self->client_connected ($cid);
+ $self->handle_protocol ($cid);
+}
+
+#start a tcp server on $self->port
+sub tcp_listen{
+ my $self = shift;
tcp_server undef, $self->port, sub {
my ($fh, $h, $p) = @_;
@@ -128,14 +163,14 @@ sub listen {
$self->client_disconnected ($cid, "error: $msg");
},
);
- $self->{clients}->{$cid} = $hdl;
-
+ #sockets are bidirectional. use same handle for in & out.
+ $self->{clients}->{$cid}{out} = $hdl;
+ $self->{clients}->{$cid}{in} = $hdl;
$self->client_connected ($cid);
$self->handle_protocol ($cid);
};
vox_log (info => "Listening for clients on port %d", $self->port);
- $self->_cv->recv();
}
sub shutdown {
@@ -150,7 +185,7 @@ sub shutdown {
sub handle_protocol {
my ($self, $cid) = @_;
- $self->{clients}->{$cid}->push_read (packstring => "N", sub {
+ $self->{clients}->{$cid}{in}->push_read (packstring => "N", sub {
my ($handle, $string) = @_;
$self->handle_packet ($cid, data2packet ($string));
$self->handle_protocol ($cid);
@@ -162,7 +197,7 @@ sub send_client {
#print (%$hdr, "\n") and confess unless $body;
$body //= '';
- $self->{clients}->{$cid}->push_write (packstring => "N", packet2data ($hdr, $body));
+ $self->{clients}->{$cid}{out}->push_write (packstring => "N", packet2data ($hdr, $body));
if (!grep { $hdr->{cmd} eq $_ } qw/chunk activate_ui/) {
vox_log (network => "send[%d]> %s: %s", length ($body), $hdr->{cmd}, join (',', keys %$hdr));
@@ -196,7 +231,7 @@ sub push_transfer {
return unless $t;
my $data = shift @$t;
- $self->{clients}->{$cid}->push_write (packstring => "N", $data);
+ $self->{clients}->{$cid}{out}->push_write (packstring => "N", $data);
unless (@$t) {
$self->send_client ($cid, { cmd => "transfer_end" });
delete $self->{transfer}->{$cid};
Please sign in to comment.
Something went wrong with that request. Please try again.