Skip Menu |

This queue is for tickets about the Net-WebSocket-Server CPAN distribution.

Report information
The Basics
Id: 104989
Status: resolved
Priority: 0/
Queue: Net-WebSocket-Server

People
Owner: TOPAZ [...] cpan.org
Requestors: vakulya [...] dcs.uni-pannon.hu
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: SIGPIPE handling
Date: Fri, 05 Jun 2015 15:59:34 +0200
To: <bug-Net-WebSocket-Server [...] rt.cpan.org>
From: VAKULYA Gergely <vakulya [...] dcs.uni-pannon.hu>
Hi! This module lacks SIGPIPE handling. To reproduce the bug I wrote a simple app. - Start the app. - Connect to the websocket from browser, from another computer. - Cut the network connection of the browser. - Wait for the TCP timeout. When the socket associated to the connection to the browser timeouts, a SIGPIPE will occur and the WebSocket app will lose its functionality. I use Arch Linux (32-bit, Linux Flow 4.0.3-1-ARCH #1 SMP PREEMPT Wed May 13 15:53:40 CEST 2015 i686 GNU/Linux), Perl v5.20.2, Net-WebSocket-Server-0.003001. The code: #!/usr/bin/perl -w use strict; use Net::WebSocket::Server; use Data::Dumper; my $ws; my $ticks=0; #---------------------------------------------------------------------- sub on_tick { print "TICK ".$ticks."\n"; $ticks++; foreach my $conn ($ws->connections()) { $conn->send_utf8($ticks); } } #---------------------------------------------------------------------- $SIG{PIPE} = sub { print "SIGPIPE!\n"; open(LOG, ">>log"); print LOG "SIGPIPE\n"; print LOG "Server shutdown\n"; close(LOG); $ws->shutdown; warn "Broken pipe\n" }; #---------------------------------------------------------------------- $ws=Net::WebSocket::Server->new( listen => 7301, on_connect => sub { print "New WebSocet connection.\n"; my ($serv, $conn) = @_; $conn->on( handshake => sub { my ($conn, $handshake) = @_; #$conn->disconnect() unless $handshake->req->origin eq $origin; }, utf8 => sub { my ($conn, $msg) = @_; $_->send_utf8($msg) for $conn->server->connections; }, binary => sub { my ($conn, $msg) = @_; $_->send_binary($msg) for $conn->server->connections; }, disconnect => sub { print "Disconnected\n"; } ); }, tick_period => 1, on_tick => \&on_tick, ); while(1) { open(LOG, ">>log"); print LOG "Server respawned\n"; close(LOG); $ws->start; sleep(1); print "What?\n"; } 8< ------------------------------------------------- The relevant part of the output: TICK 0 TICK 1 TICK 2 TICK 3 TICK 4 TICK 5 TICK 6 TICK 7 TICK 8 TICK 9 TICK 10 TICK 11 TICK 12 TICK 13 New WebSocet connection. TICK 14 TICK 15 TICK 16 Disconnected TICK 17 New WebSocet connection. TICK 18 TICK 19 Disconnected New WebSocet connection. TICK 20 TICK 21 TICK 22 Disconnected New WebSocet connection. TICK 23 TICK 24 Disconnected New WebSocet connection. TICK 25 Disconnected New WebSocet connection. TICK 26 Disconnected New WebSocet connection. Disconnected TICK 27 New WebSocet connection. Disconnected TICK 28 New WebSocet connection. Disconnected New WebSocet connection. TICK 29 Disconnected New WebSocet connection. TICK 30 TICK 31 TICK 32 TICK 33 TICK 34 TICK 35 TICK 36 [Note: 1 WebSocket connection at this point. Net connection is cut here.] TICK 962 TICK 963 TICK 964 TICK 965 TICK 966 TICK 967 TICK 968 Disconnected SIGPIPE! Broken pipe What? What? What? What? What? What? What? What? What? Thank you for your help! Best regards, Antiemes
Thanks for the bug report! This should be fixed in 0.3.2. CPAN will have it available shortly, or you can pull down the latest version for testing from GitHub: https://github.com/topaz/perl-Net-WebSocket-Server The SIGPIPE handling, after much experimentation including registering/unregistering local $SIG{PIPE} handlers around every syswrite, amounted to a blanket $SIG{PIPE}='IGNORE'. In your test, you were also calling ->start() after calling ->shutdown(), which caused the other issue you experienced in which the server permanently failed to start. This was because it was trying to re-use the old, closed listening socket. There is now an additional check for that situation in the ->start() method.