Skip to content

Commit

Permalink
improved WebSocket and long poll performance
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Mar 3, 2014
1 parent a7ed2b8 commit ac9a001
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 14 deletions.
3 changes: 2 additions & 1 deletion Changes
@@ -1,6 +1,7 @@

4.86 2014-03-03
- Improved Mojo::IOLoop::Delay to allow more method chaining.
- Improved WebSocket and long poll performance.

4.85 2014-02-26
- Added next_tick method to Mojo::IOLoop and Mojo::Reactor.
Expand Down Expand Up @@ -2734,7 +2735,7 @@
- Improved Mojo::Parameters performance. (kimoto)
- Improved Mojo::Message::Response parser resilience.
- Improved template class handling in MojoX::Renderer. (vti)
- Fixed a serious design flaw in Mojo::Message and made long poll much
- Fixed a serious design flaw in Mojo::Message and made long polling much
easier.
- Fixed a bug where Mojo::IOLoop connections could be closed too early.
- Fixed a bug where a broken renderer could cause a fatal exception.
Expand Down
18 changes: 7 additions & 11 deletions lib/Mojolicious/Controller.pm
Expand Up @@ -70,14 +70,11 @@ sub finish {
$tx->finish(@_) and return $self if $tx->is_websocket;

# Chunked stream
if ($tx->res->content->is_chunked) {
$self->write_chunk(@_) if @_;
return $self->write_chunk('');
}
return @_ ? $self->write_chunk(@_)->write_chunk('') : $self->write_chunk('')
if $tx->res->content->is_chunked;

# Normal stream
$self->write(@_) if @_;
return $self->write('');
return @_ ? $self->write(@_)->write('') : $self->write('');
}

sub flash {
Expand All @@ -99,7 +96,7 @@ sub on {
my ($self, $name, $cb) = @_;
my $tx = $self->tx;
$self->rendered(101) if $tx->is_websocket;
return $tx->on($name => sub { shift and $self->$cb(@_) });
return $tx->on($name => sub { shift; $self->$cb(@_) });
}

sub param {
Expand Down Expand Up @@ -251,7 +248,7 @@ sub send {
my $tx = $self->tx;
Carp::croak 'No WebSocket connection to send message to'
unless $tx->is_websocket;
$tx->send($msg => sub { shift and $self->$cb(@_) if $cb });
$tx->send($msg, $cb ? sub { shift; $self->$cb(@_) } : ());
return $self->rendered(101);
}

Expand Down Expand Up @@ -366,16 +363,15 @@ sub validation {
sub write {
my ($self, $chunk, $cb) = @_;
($cb, $chunk) = ($chunk, undef) if ref $chunk eq 'CODE';
my $content = $self->res->content;
$content->write($chunk => sub { shift and $self->$cb(@_) if $cb });
$self->res->content->write($chunk, $cb ? sub { shift; $self->$cb(@_) } : ());
return $self->rendered;
}

sub write_chunk {
my ($self, $chunk, $cb) = @_;
($cb, $chunk) = ($chunk, undef) if ref $chunk eq 'CODE';
my $content = $self->res->content;
$content->write_chunk($chunk => sub { shift and $self->$cb(@_) if $cb });
$content->write_chunk($chunk, $cb ? sub { shift; $self->$cb(@_) } : ());
return $self->rendered;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/Mojolicious/Guides/Cookbook.pod
Expand Up @@ -349,7 +349,7 @@ for some reason can't just be integrated with a new reactor backend.
=head1 REAL-TIME WEB

The real-time web is a collection of technologies that include Comet
(long-polling), EventSource and WebSockets, which allow content to be pushed
(long polling), EventSource and WebSockets, which allow content to be pushed
to consumers with long-lived connections as soon as it is generated, instead
of relying on the more traditional pull model. All built-in web servers use
non-blocking I/O and are based on the L<Mojo::IOLoop> event loop, which
Expand Down Expand Up @@ -600,7 +600,7 @@ L<Test::Mojo> API to be used.

=head2 EventSource web service

EventSource is a special form of long-polling where you can use
EventSource is a special form of long polling where you can use
L<Mojolicious::Controller/"write"> to directly send DOM events from servers to
clients. It is uni-directional, that means you will have to use Ajax requests
for sending data from clients to servers, the advantage however is low
Expand Down
4 changes: 4 additions & 0 deletions t/mojolicious/dispatch.t
Expand Up @@ -222,4 +222,8 @@ is $c->param('action'), undef, 'no value';
is $c->param('capture'), 'привет', 'right value';
ok $c->render_called, 'rendered';

# Not a WebSocket transaction
eval { $c->send('test') };
like $@, qr/^No WebSocket connection to send message to/, 'right error';

done_testing();

0 comments on commit ac9a001

Please sign in to comment.