首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WebSockets +WebSockets不工作

WebSockets +WebSockets不工作
EN

Stack Overflow用户
提问于 2016-01-12 13:02:13
回答 1查看 1.6K关注 0票数 2

让我们从头开始:我已经安装了Wamp Server (版本: 2.4.9,php: 5.5.12),我想用web创建一个简单的聊天。

很好,为此我创建了两个文件:

Connect.js

代码语言:javascript
复制
window.onload = function() { 

var form = document.getElementById('mensagem-formulario'); 
var mensagemTexto = document.getElementById('mensagem');
var listaMensagem = document.getElementById('mensagens');
var socketStatus = document.getElementById('status'); 
var btnFechar = document.getElementById('close'); 

var socket = new WebSocket('ws://localhost:8080');

socket.onopen = function(event) { 

socketStatus.innerHTML = 'Connect with ' + event.currentTarget.URL; socketStatus.className = 'open'; 

};

socket.onerror = function(error) { 

console.log('Error: ' + error); 

socketStatus.innerHTML = 'Error: ' + error;

};

form.onsubmit = function(e) { e.preventDefault(); /
var mensagem = mensagemTexto.value; 
socket.send(mensagem); 
listaMensagem.innerHTML += '<li class="envia"><span>Enviado:</span>' + mensagem + '</li>'; 
mensagemTexto.value = ''; return false; 

};

socket.onmessage = function(event) { 
var mensagem = event.data; listaMensagem.innerHTML += '<li class="recebida"><span>Recebida:</span>' + mensagem + '</li>'; 
};

socket.onclose = function(event) { 

socketStatus.innerHTML = 'Disconectado do WebSocket.'; socketStatus.className = 'closed'; 

};

btnFechar.onclick = function(e) { 
e.preventDefault(); 
socket.close(); return false; 
};

};

Server.php

代码语言:javascript
复制
<?php

    $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
    socket_bind($server, "localhost", 8080);
    socket_listen($server);

    $client = socket_accept($server);

    $message = socket_read($client, 5000);

    $matches = array();

    preg_match('#Sec-WebSocket-Key: (.*)\r\n#', $message, $matches);

    $new_key = new_key($matches[1]);

    $new_message = "HTTP/1.1 101 Switching Protocols\r\n";
    $new_message .= "Upgrade: websocket\r\n";
    $new_message .= "Connection: Upgrade\r\n";
    $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";

    socket_write($client, $new_message, strlen($new_message));

    $new_message = "Test message !";

    socket_write($client, $new_message, strlen($new_message));

    function new_key($key)
    {
        $key .= "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
        $key = sha1($key);
        $new_key = '';

        for ($i = 0; $i < strlen($key); $i+=2)
        {
            $new_key .= chr(intval($key[$i] . $key[$i+1], 16));
        }

        $new_key = base64_encode($new_key);

        return $new_key;
    }

    /* End of file server.php */

    ?>

太好了,现在让我们测试一下这段代码:

  • 首先启动我的Wamp服务器
  • 现在我在浏览器中打开文件server.php。
  • 太好了,我认为连接是打开的(因为文件不会停止加载)
  • 现在是打开connect.js并查看结果的时候了。

当我打开connect.js将server.php停止加载到另一个选项卡中时,在控制台日志javascript中向我发送以下错误:

到'ws://localhost:8080/‘的WebSocket连接失败:一个或多个保留位已打开: reserved1 = 1,reserved2 = 0,reserved3 =1

我该如何解决这个问题?是语法问题还是服务器问题?(我不想使用node.js、socket.io和其他工具,我只是尝试手工操作)。

EN

回答 1

Stack Overflow用户

发布于 2016-01-12 21:28:51

解决方案

此代码的问题在于php服务器,因此如果您有相同的问题,您需要创建一个名为server.php的新文件,并将下面的代码放在他的内部:

代码语言:javascript
复制
<?php
error_reporting(E_ALL);
set_time_limit(0);
$adr = "localhost";
echo $adr."\n\n";
$port = 8080;

$m_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($m_sock, SOL_SOCKET, SO_REUSEADDR, 1);
$cls = array($m_sock);

socket_bind($m_sock, $adr, $port);
socket_listen($m_sock, 5);
echo "Starting server...\n\n";

do{
    usleep(500);
    $changed = $cls;
    $val = @socket_select($changed,$write=NULL,$except=NULL,0);
    foreach ($changed as $sock) {
        if($sock === $m_sock){
            echo "wait...\n\n";
            $msgsock = socket_accept($m_sock);
            array_push($cls, $msgsock);
            echo "Connected...\n\n";
            socket_recv($msgsock, $hds, 4096, 0);

            if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$hds,$matchs)){
                echo "do handshake...\n\n";

                $key = $matchs[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
                $key =  base64_encode(sha1($key, true)); 
                $headers = "HTTP/1.1 101 Switching Protocols\r\n".
                "Upgrade: websocket\r\n".
                "Connection: Upgrade\r\n".
                "Sec-WebSocket-Accept: $key".
                "\r\n\r\n";
                socket_write($msgsock, $headers);
                echo "handshak done...\n";
            }
        }else{
            $bytes = socket_recv($sock, $data, 2048, null);
            $d = unmask($data);
            foreach ($cls as $socket) {
                if($socket != $m_sock && $val > 0){
                    try{
                       socket_write($socket,(encode($d))); 
                    }catch(Exception $e){
                        unset($cls[$socket]);
                        socket_close($cls[$socket]);
                    }
                }
            }
        }
    } 


}while(1);
socket_close($m_sock);


function unmask($payload) {
    $length = ord($payload[1]) & 127;

    if($length == 126) {
        $masks = substr($payload, 4, 4);
        $data = substr($payload, 8);
    }
    elseif($length == 127) {
        $masks = substr($payload, 10, 4);
        $data = substr($payload, 14);
    }
    else {
        $masks = substr($payload, 2, 4);
        $data = substr($payload, 6);
    }

    $text = '';
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i%4];
    }
    return $text;
}

function encode($text)
{
    // 0x1 text frame (FIN + opcode)
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);

    if($length <= 125)
        $header = pack('CC', $b1, $length);
    elseif($length > 125 && $length < 65536)
        $header = pack('CCS', $b1, 126, $length);
    elseif($length >= 65536)
        $header = pack('CCN', $b1, 127, $length);

    return $header.$text;
}


?>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34744436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档