prabhakaran
prabhakaran

Reputation: 5274

Firefox - WebSocket - Is not establishing connection

I am trying to send some message through Websocket to the server. The web page contains a simple html with javascript. This is the html file "delete_This.html".

<html>
<head>
<script type="text/javascript" src="delete_This.js"></script>
</head>
<body>
<h1>My First Web Page</h1>
<p id="demo"></p>

<input type="button" onclick="show()" value="Display Confirm">
</body>
</html>

This is javascript file "delete_This.js".

function show()
{
    var port = "8080";
    var address_0="ws://192.168.1.2:" + port;
    var address_1="ws://127.0.0.1:" + port;
    var address_2="ws://localhost:" + port;
    var ws;
    if ("WebSocket" in window)
    ws = new WebSocket(address_2); //843
    else if("MozWebSocket" in window)
    ws = new MozWebSocket(address_2); //843
    else
    alert("WebSockets NOT supported here!rnrnBrowser: " + navigator.appName + " " + navigator.appVersion + "rnrntest by jimbergman.net (based on Google sample code)");

    try
    {
    ws.onmessage = function (evt) 
    {
        var received_msg = evt.data; 
    };

    ws.onopen = function(evt)
    {
        alert("connection opened");
        // Web Socket is connected. You can send data by send() method
        ws.send("message to send");
    };

    ws.onclose = function() 
    {
        // websocket is closed. };
        alert("WebSockets supported here!rnrnBrowser: " + navigator.appName + " " + navigator.appVersion + "rnrntest by jimbergman.net (based on Google sample code)");
    }
    }
    catch(evt)
    {
        alert(evt.data);
    }

}

This is server side perl script "socketpolicy.pl".

use Socket;
use IO::Handle;

STDOUT->autoflush(1);
my $should_be_logging = 1;  # change to 0 to turn off logging.

my $logfile = 'log';

if ($should_be_logging) 
{
    open(LOG, ">$logfile") or warn "Can't open $logfile: $!\n";
    LOG->autoflush(1);
}

my $port = 8080; #843

my $proto = getprotobyname('tcp');

# start the server:
#&log("Starting server on port $port");
 print "Starting server on port $port\n";
socket(Server, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 1 ) or die "setsockopt: $!";
bind(Server,sockaddr_in($port,INADDR_ANY)) or die "bind: $!";
print "binding happened\n";
listen(Server,SOMAXCONN) or die "listen: $!";

Server->autoflush( 1 );

my $paddr;
#&log("Server started. Waiting for connections.");
print "Server started. Waiting for connections.\n";

$/ = "\0";      # reset terminator to null char

# listening loop.

for ( ; $paddr = accept(Client,Server); close Client) 
{
    print "one connection accepted\n";
    Client->autoflush(1);
    my($port,$iaddr) = sockaddr_in($paddr);
    my $ip_address   = inet_ntoa($iaddr);
    my $name         = gethostbyaddr($iaddr,AF_INET) || $ip_address;
    #&log( scalar localtime() . ": Connection from $name" );
print ( scalar localtime() . ": Connection from $name\n" );

    #print STDOUT <Client>;
    #print Client "Welcome";
    my $line = <Client>;
    #&log("Input: $line");
    print STDOUT $line;
    my $client_Sent_Key;
    if ($line =~ /("Sec-WebSocket-Key:")(.*)/i)
    {
        $client_Sent_Key = $2;
    print STDOUT $client_Sent_Key;
    }

    print Client "Hello World";
    #if ($line =~ /.*policy\-file.*/i) 
    #{
    #    print Client &xml_policy;
    #}
}

sub xml_policy 
{
    my $str = qq(<cross-domain-policy><allow-access-from domain="*" to-ports="*" />  </cross-domain-policy>\0);
    return $str;
}

sub log
{
    my($msg) = @_;
    if ($should_be_logging) 
   {
       print LOG $msg,"\n";
   #print $msg,"\n";
   }
}

The interesting thing is server is accepting the connection and showing that it got one connection. But, the client(Firefox Browser) is showing that the connection is not established. And there is message sent from the client side to the server side. This is the server side display.

C:\Documents and Settings\prabhakaran\Desktop>perl socketpolicy.pl
Starting server on port 8080
binding happened
Server started. Waiting for connections.
one connection accepted
Tue Mar  6 21:50:47 2012: Connection from localhost

This is the debug information in client side by FireBug

Firefox can't establish a connection to the server at ws://localhost:8080/.
ws = new MozWebSocket(address_2); //843             delete_This.js (line 44)

The mystery is this part. After I closed the page in the browser. The server is receiving some messages from the client. This is the server side display. The new message starts after "Connection from localhost".

C:\Documents and Settings\prabhakaran\Desktop>perl socketpolicy.pl
Starting server on port 8080
binding happened
Server started. Waiting for connections.
one connection accepted
Tue Mar  6 21:50:47 2012: Connection from localhost
GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.
2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive, Upgrade
Sec-WebSocket-Version: 8
Sec-WebSocket-Origin: null
Sec-WebSocket-Extensions: deflate-stream
Sec-WebSocket-Key: riHRie5CtAA9Z7sHOobAMg==
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

My Questions are

1)How to establish the connection successfully?

2)How to make the WebSocket to send the messages instantly?

If anybody give answers for these questions, I will be very thankful to them.

Note: I am using Firefox 10.0.0.2,Windows Platform, and Strawberry Perl.

Upvotes: 1

Views: 9042

Answers (1)

kanaka
kanaka

Reputation: 73091

Your server is attempting to treat WebSocket connections as normal socket connections. But WebSocket connections have their own protocol. See the IETF 6455 specificiation.

In summary:

  • WebSocket connections have an HTTP friendly handshake that the server must respond correctly to (the client won't register the connection as open until the server responds correctly). Among other things, this handshake makes it much easier to run WebSocket servers on the same port as a webserver (and re-use existing firewall configuration). The handshake also allows some level of CORS security.
  • Each WebSocket frame/message includes a a header that includes the payload length and payload type among other things. In the case of browser to server frames (but not server to browser frames), the payload is also masked using a 4-byte running XOR mask applied to the payload. The mask data is included as the first 4 bytes after the header.

Update:

In your specific code:

my $line = <Client>;

is really designed for file I/O and that it is trying to read the whole file. This means it will not return until it reaches the end of file. In a socket context, EOF means when the socket closes. I think you really want something more raw like a standard socket recv call. You will need to recv until you receive '\r\n\r\n' indicating the end of the handshake and then you will need to split what you have accumulated into individual headers lines for processing.

Upvotes: 2

Related Questions