Javascript WebSocket连接在Mojolicous中延迟

Javascript WebSocket连接在Mojolicous中延迟,javascript,perl,websocket,mojolicious,Javascript,Perl,Websocket,Mojolicious,我想我在我迷人的WebSocket中做了一些愚蠢的事情,有一个简单的解决办法 我有一个表单,发布后会启动一个WebSocket来接收进度文本。问题是,在我发出finish()命令之前,连接不会完成。此时,我的浏览器实际上打开了套接字并接收所有消息 我假设我在服务器端做了一些错误的事情,但我不能排除javascript是问题所在 javascript $(document).ready(function() { $("form.report_form").submit(function(eve

我想我在我迷人的WebSocket中做了一些愚蠢的事情,有一个简单的解决办法

我有一个表单,发布后会启动一个WebSocket来接收进度文本。问题是,在我发出finish()命令之前,连接不会完成。此时,我的浏览器实际上打开了套接字并接收所有消息

我假设我在服务器端做了一些错误的事情,但我不能排除javascript是问题所在

javascript

$(document).ready(function() {
  $("form.report_form").submit(function(event) {
    event.preventDefault();

/* do the POSTy things */

    var ws = new WebSocket($('#progress_url').val());
    ws.onopen = function(){ alert('websocket is ready for business')};
    ws.onmessage = function (event) {
      console.log(event.data);
    }           
  });

/* stuff to configure the form */

});
魅力控制器

package WebLOC::Controller::Progress;
use Mojo::Base 'Mojolicious::Controller';

sub tail {
    my $self = shift;

    my ($guid)
        = $self->url_for
        =~ /([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})/;

    my $filename = "/tmp/$guid.out";

    my $fh;
    my $is_open = open( $fh, '<', $filename );
    unless ($is_open) {    # try one more time
        sleep 1; 
        $is_open = open( $fh, '<', $filename );
    }

    if ($is_open) {
        $self->inactivity_timeout( 5 * 60 );

        # shouldn't need a subscription, but...
        $self->on( finish => sub { } );

        while ( my $msg = <$fh> ) {
            chomp $msg;

            $self->send(
                $msg => sub { $self->app->log->debug('I am drained') } );

            $self->app->log->debug("read: $msg");
        }
    }
    else {
        $self->app->log->error("Can't open file $filename: $!");

        return; 
    }

    $self->finish;

    return 0;
}

1;
sub websocket {
    my $self = shift;

    my $guid = $self->stash('guid');

    $self->on( finish => sub { delete $self->stash->{websockets}{$guid} } );

    $self->stash->{websockets}{$guid} = $self->tx;
}           
my $fork = Mojo::IOLoop::ReadWriteFork->new;

$fork->on(
    read => sub {
        my ( undef, $msg ) = @_;

        chomp $msg;

        my $websocket = $self->stash->{websockets}{$key};

        $websocket->send($msg) if $websocket;
    }
);

$fork->on(
    close => sub {
        my ( undef, $err ) = @_;

        my $websocket = $self->stash->{websockets}{$key};

        $websocket->finish if $websocket;

    }
);
mojolicous Log

[Wed Nov 22 14:35:31 2017] [debug] GET "/progress/53898C2E-CFC8-11E7-B15D-BCDD6A63D34C"
[Wed Nov 22 14:35:31 2017] [debug] Routing to controller "WebLOC::Controller::Auth" and action "check"
[Wed Nov 22 14:35:31 2017] [debug] Routing to controller "WebLOC::Controller::Progress" and action "tail"
[Wed Nov 22 14:35:31 2017] [debug] 101 Switching Protocols (0.008343s, 119.861/s)
[Wed Nov 22 14:35:33 2017] [debug] read: 1 of 3
[Wed Nov 22 14:35:36 2017] [debug] read: 2 of 3
[Wed Nov 22 14:35:39 2017] [debug] read: 3 of 3
[Wed Nov 22 14:35:42 2017] [debug] I am drained
[Wed Nov 22 14:35:42 2017] [debug] I am drained
[Wed Nov 22 14:35:42 2017] [debug] I am drained
日志显示文件读取(和WS-sends)是实时进行的,但是直到最后发送才被耗尽。我还可以看到WebSocket没有显示已建立()。在客户端,在服务器上关闭连接之前,我不会获取onopen alert()或onmessage控制台日志

已解决 据我所知,WebSocket在控制器退出后才能使用。我想在这之前有一种方法可以强迫它工作,但我确实想不出来

我改变了我的设计。我没有尝试立即将数据发送到套接字,而是将tx()对象存储在一个隐藏散列中。然后让脚本的输出发送到该事务

迷人的应用程序

select STDOUT;
$|=1;

say "1 of 3";
sleep 3;
say "2 of 3";
sleep 3;
say "3 of 3";
sleep 3;
exit;
$self->defaults( layout => 'default', websockets => {}, );
...
$auth->websocket('/progress/:guid')->to('progress#websocket');
WebSocket控制器

package WebLOC::Controller::Progress;
use Mojo::Base 'Mojolicious::Controller';

sub tail {
    my $self = shift;

    my ($guid)
        = $self->url_for
        =~ /([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})/;

    my $filename = "/tmp/$guid.out";

    my $fh;
    my $is_open = open( $fh, '<', $filename );
    unless ($is_open) {    # try one more time
        sleep 1; 
        $is_open = open( $fh, '<', $filename );
    }

    if ($is_open) {
        $self->inactivity_timeout( 5 * 60 );

        # shouldn't need a subscription, but...
        $self->on( finish => sub { } );

        while ( my $msg = <$fh> ) {
            chomp $msg;

            $self->send(
                $msg => sub { $self->app->log->debug('I am drained') } );

            $self->app->log->debug("read: $msg");
        }
    }
    else {
        $self->app->log->error("Can't open file $filename: $!");

        return; 
    }

    $self->finish;

    return 0;
}

1;
sub websocket {
    my $self = shift;

    my $guid = $self->stash('guid');

    $self->on( finish => sub { delete $self->stash->{websockets}{$guid} } );

    $self->stash->{websockets}{$guid} = $self->tx;
}           
my $fork = Mojo::IOLoop::ReadWriteFork->new;

$fork->on(
    read => sub {
        my ( undef, $msg ) = @_;

        chomp $msg;

        my $websocket = $self->stash->{websockets}{$key};

        $websocket->send($msg) if $websocket;
    }
);

$fork->on(
    close => sub {
        my ( undef, $err ) = @_;

        my $websocket = $self->stash->{websockets}{$key};

        $websocket->finish if $websocket;

    }
);
报告控制器

package WebLOC::Controller::Progress;
use Mojo::Base 'Mojolicious::Controller';

sub tail {
    my $self = shift;

    my ($guid)
        = $self->url_for
        =~ /([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})/;

    my $filename = "/tmp/$guid.out";

    my $fh;
    my $is_open = open( $fh, '<', $filename );
    unless ($is_open) {    # try one more time
        sleep 1; 
        $is_open = open( $fh, '<', $filename );
    }

    if ($is_open) {
        $self->inactivity_timeout( 5 * 60 );

        # shouldn't need a subscription, but...
        $self->on( finish => sub { } );

        while ( my $msg = <$fh> ) {
            chomp $msg;

            $self->send(
                $msg => sub { $self->app->log->debug('I am drained') } );

            $self->app->log->debug("read: $msg");
        }
    }
    else {
        $self->app->log->error("Can't open file $filename: $!");

        return; 
    }

    $self->finish;

    return 0;
}

1;
sub websocket {
    my $self = shift;

    my $guid = $self->stash('guid');

    $self->on( finish => sub { delete $self->stash->{websockets}{$guid} } );

    $self->stash->{websockets}{$guid} = $self->tx;
}           
my $fork = Mojo::IOLoop::ReadWriteFork->new;

$fork->on(
    read => sub {
        my ( undef, $msg ) = @_;

        chomp $msg;

        my $websocket = $self->stash->{websockets}{$key};

        $websocket->send($msg) if $websocket;
    }
);

$fork->on(
    close => sub {
        my ( undef, $err ) = @_;

        my $websocket = $self->stash->{websockets}{$key};

        $websocket->finish if $websocket;

    }
);