Firefox - WebSocket - не устанавливается соединение - PullRequest
1 голос
/ 06 марта 2012

Я пытаюсь отправить какое-то сообщение через Websocket на сервер. Веб-страница содержит простой HTML с JavaScript. Это HTML-файл "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>

Это файл JavaScript "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);
    }

}

Это серверный сценарий Perl "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";
   }
}

Интересно, что сервер принимает соединение и показывает, что он получил одно соединение. Но клиент (Firefox Browser) показывает, что соединение не установлено. И есть сообщение, отправленное со стороны клиента на сторону сервера. Это дисплей на стороне сервера.

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

Это отладочная информация на стороне клиента от 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)

Тайна в этой части. После того как я закрыл страницу в браузере. Сервер получает некоторые сообщения от клиента. Это дисплей на стороне сервера. Новое сообщение начинается после «Соединение с локального узла».

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

Мои вопросы

1) Как успешно установить соединение?

2) Как заставить WebSocket отправлять сообщения мгновенно?

Если кто-нибудь даст ответы на эти вопросы, я буду им очень благодарен.

Примечание. Я использую Firefox 10.0.0.2, платформу Windows и Strawberry Perl.

1 Ответ

2 голосов
/ 06 марта 2012

Ваш сервер пытается обработать соединения WebSocket как обычные соединения с сокетами.Но соединения WebSocket имеют свой собственный протокол.См. Спецификацию IETF 6455 .

В итоге:

  • Соединения WebSocket имеют дружественное HTTP-рукопожатие, на которое сервер должен правильно ответить (клиент не будетзарегистрируйте соединение как открытое, пока сервер не ответит правильно).Помимо прочего, это рукопожатие значительно упрощает запуск серверов WebSocket на том же порту, что и веб-сервер (и повторное использование существующей конфигурации брандмауэра).Такое рукопожатие также обеспечивает некоторый уровень безопасности CORS.
  • Каждый кадр / сообщение WebSocket включает в себя заголовок, который включает в себя длину полезной нагрузки и тип полезной нагрузки, среди прочего.В случае фреймов браузер-сервер (но не фреймы сервер-браузер) полезная нагрузка также маскируется с использованием 4-байтовой рабочей маски XOR, применяемой к полезной нагрузке.Данные маски включаются в первые 4 байта после заголовка.

Обновление :

В вашем конкретном коде:

my $line = <Client>;

действительно предназначен для файлового ввода-вывода и пытается прочитать весь файл.Это означает, что он не вернется, пока не достигнет конца файла.В контексте сокета EOF означает, когда сокет закрывается.Я думаю, что вы действительно хотите что-то более сырое, как стандартный вызов сокета recv.Вам нужно будет выполнять recv до тех пор, пока вы не получите '\ r \ n \ r \ n', указывающий конец рукопожатия, а затем вам нужно будет разделить то, что вы накопили, на отдельные строки заголовков для обработки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...