WebSocket服务器从头开始显示操作码-1

时间:2019-03-21 13:23:28

标签: perl websocket

我试图从头开始在perl中创建一个简单的WebSocket服务器,当我在Google Chrome浏览器中尝试使用它时,它给了我 opcode -1 ,我该如何解决?

websocket.pl

#!/usr/bin/perl -w
use strict;
use IO::Socket::INET;
use Digest::SHA1 "sha1_base64";

$| = 1;

my $magic_string = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";


# Create a server
my $socket = IO::Socket::INET->new( LocalHost => 'localhost',
                                    LocalPort => 7777,
                                    Proto     => 'tcp',
                                    Listen    => 5,
                                    Reuse     => 1
) || die "$!";

print "Server is running on port 7777\n";


while (1) {
    my $client = $socket->accept();
    my $key = "";

    # Get the Request
    my $data = "";
    while (my $line = <$client>) {
            $data .= $line;
    }

    # Get the Sec-WebSocket-Key value
      foreach my $line ( split /\n/ => $data ) {
          if ( $line =~ /^Sec-WebSocket-Key: (\S+)/ ) {
                  $key = $1;
            }
      }
      print "Sec-WebSocket-Key: $key\n";

      # Create the Sec-WebSocket-Accept header value
      my $accept = sha1_base64($key);
      $accept .= "="x(4-(length($accept)%4));
      print "Sec-WebSocket-Accept: $accept\n";

      # Response
      print $client "HTTP/1.1 101 Switching Protocols\r\n";
      print $client "Upgrade: websocket\r\n";
      print $client "Connection: Upgrade\r\n";
      print $client "Sec-WebSocket-Accept: $accept\r\n\r\n";

      shutdown($client, 1);
}

$socket->close();

我很确定返回网站的密钥是正确的,那么问题出在哪里呢?出了什么问题?

ws.js

var ws = new WebSocket("ws://localhost:7777/");

ws.onopen = function() {
    alert("connected!");
    ws.send( 'Hello server' );
};

ws.onclose = function() {
    alert( 'Connection is closed... ');
};

Web Browser network traffic

编辑

Stefan Becker :是的,我知道,但是在这种情况下,我确定请求小于1024字节,我已将其修复,谢谢。

1 个答案:

答案 0 :(得分:1)

(Opcode -1)是一般错误。就您而言,这是错误的Sec-WebSocket-Accept标头。您忘记使用$magic_string

my $accept = sha1_base64($key.$magic_string);

while (my $line = <$client>) {也可能永远运行。您需要检查是否有空行。