【问题标题】:php websocket problemphp websocket问题
【发布时间】:2011-08-04 11:27:12
【问题描述】:

我是 Web 套接字的新手。我制作了我的第一个 Web 套接字,但现在运行它时遇到问题!

这是socket的代码

// set some variables 
$host = "127.0.0.1"; 
$port = 1234; 

// don't timeout! 
set_time_limit(0); 

// create socket 
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n"); 
if($socket){
    echo "socket created .... $socket\n";
}

// bind socket to port 
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n"); 
if($result){
    echo "socket binded ... $result\n";
}
// start listening for connections 
$result = socket_listen($socket, 3) or die("Could not set up socket listener\n"); 
if($result){
    echo "socket is now listening ... $result";
}
// accept incoming connections 
// spawn another socket to handle communication 
$spawn = socket_accept($socket) or die("Could not accept incoming connection\n"); 
if($spawn){
    echo $spawn."\n";
}
// read client input 
$input = socket_read($spawn, 1024) or die("Could not read input\n"); 
if($input){
    echo $input."\n";
}
// clean up input string 
$input = trim($input); 

// reverse client input and send back 
$output = strrev($input) . "\n"; 
socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n"); 

// close sockets 
socket_close($spawn); 
socket_close($socket);

现在我该如何运行这段代码??我在我的 xampp shell 上写了以下代码:

php htdocs/socket/server.php -q

它显示:

socket created....Resource id #4
socket binded... 1
socket is now listening...1 Resource is #5
GET socket/server.php HTTP 1.1
upgrade: WebSocket
connection: Upgrade
Host: http://localhost
sec-WebSocket-key1: 14 53    8501 z4 5R'
sec-WebSocket-key2: S 9\ 2s63, *8460!~MO@

现在我该如何运行它.. 我如何向它发送输入以及如何将它与 JavaScript 一起使用??

我编写了一段 JavaScript 代码,但它连接了一秒钟然后断开连接...

这里是javascipt代码:

$(document).ready(function() {

if(!("WebSocket" in window)){
    $('#chatLog, input, button, #examples').fadeOut("fast");    
    $('<p>Oh no, you need a browser that supports WebSockets. How about <a   href="http://www.google.com/chrome">Google Chrome</a>?</p>').appendTo('#container');       
}else{
    //The user has WebSockets

connect();

function connect(){
        var socket;
        var host = "ws://localhost:1234/websocket_source_files/myown.php";

        try{
            var socket = new WebSocket(host);
            message('<p class="event">Socket Status: '+socket.readyState);
            socket.onopen = function(){
                message('<p class="event">Socket Status: '+socket.readyState+' (open)');    
            }

            socket.onmessage = function(msg){
                message('<p class="message">Received: '+msg.data);                  
            }

            socket.onclose = function(){
                message('<p class="event">Socket Status: '+socket.readyState+' (Closed)');
            }           

        } catch(exception){
            message('<p>Error'+exception);
        }

        function send(){
            var text = $('#text').val();
            if(text==""){
                message('<p class="warning">Please enter a message');
                return ;    
            }
            try{
                socket.send(text);
                message('<p class="event">Sent: '+text)
            } catch(exception){
                message('<p class="warning">');
            }
            $('#text').val("");
        }

        function message(msg){
            $('#chatLog').append(msg+'</p>');
        }//End message()

        $('#text').keypress(function(event) {
                  if (event.keyCode == '13') {
                     send();
                   }
        }); 

        $('#disconnect').click(function(){
            socket.close();
        });

    }


}//End connect()

});
</script>

<title>WebSockets Client</title>

</head>
<body>
<div id="wrapper">

<div id="container">

    <h1>WebSockets Client</h1>

    <div id="chatLog">

    </div>
    <p id="examples">e.g. try 'hi', 'name', 'age', 'today'</p>

    <input id="text" type="text" />
    <button id="disconnect">Disconnect</button>

</div>

  </div>
</body>
</html>​

请帮助我运行此代码并学习网络套接字。我真的需要在我的学校项目中使用它们。

【问题讨论】:

  • 使用编辑器工具来正确格式化您的帖子,以便我们可以真正阅读它...

标签: php javascript websocket


【解决方案1】:

socket_accept-函数将阻塞(等待)直到客户端连接到它。这是标准行为。

但在连接套接字后执行的功能不会阻塞(除非您告诉他们这样做)。所以你要告诉你的脚本等到它可以从 Socket 中读取。

为此,使用socket_set_block-function。此外,您可能希望使用socket_last_error-function 检查任何可能的错误。

不过,我认为 Java 或 C 更适合使用套接字。

【讨论】:

    【解决方案2】:

    编写另一个可以连接到它的 PHP 脚本。

    【讨论】:

    • 检查javascript代码..它确实连接到套接字服务器但我无法理解和解决..为什么它会断开连接?并且shell屏幕上什么也没有显示!
    【解决方案3】:

    你没有正确地握手。

    根据您发布的内容,您正在处理 ietf-00 实现 (https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-00)

    这是旧的和不推荐使用的,最后一个似乎是 ietf-10 (https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-10)。

    您需要的握手的非常基本的描述可以在这里找到:http://en.wikipedia.org/wiki/WebSockets

    (您可以在其中找到更新的官方规范的链接)。

    在您的案例中,重要的部分是:

    Sec-WebSocket-Key1 和 Sec-WebSocket-Key2 字段以及 8 个字节 在字段是服务器用来构造的随机标记之后 握手结束时的 16 字节令牌,以证明它已读取 客户的握手。

    握手是通过连接来自 第一个键,除以空格数。然后重复 为第二把钥匙。两个结果数字与 彼此,并在字段之后的最后 8 个字节。

    最终结果是连接字符串的 MD5 和。[7]这 握手看起来像 HTTP,但实际上不是。它允许服务器 将握手请求的一部分解释为 HTTP,然后切换到 网络套接字。一旦建立,WebSocket 数据帧就可以被发回 在客户端和服务器之间以全双工模式来回切换。文本 帧可以同时在任一方向全双工发送。

    数据的最小框架只有两个字节。每一帧开始 0x00 字节,以 0xFF 字节结尾,包含 UTF-8 数据 之间。 API 中尚不支持二进制帧。网络套接字 文本框架使用终止符,而二进制框架使用长度前缀。

    现在,一些代码(这将接受一个连接,接收一条消息,然后发送一个响应,就像一个非常基本和原始的示例来展示它是如何完成的):

    // Just to log to console
    function myLog($msg)
    {
        echo date('m/d/Y H:i:s ', time()) . $msg . "\n";
    }
    
    // This will actually read and process the key-1 and key-2 variables, doing the math for them
    function getWebSocketKeyHash($key)
    {
        $digits = '';
        $spaces = 0;
        // Get digits
        preg_match_all('/([0-9])/', $key, $digits);
        $digits = implode('', $digits[0]);
        // Count spaces
        $spaces = preg_match_all("/\\s/ ", $key, $dummySpaces);
        $div = (int)$digits / (int)$spaces;
        myLog('key |' . $key . '|: ' . $digits . ' / ' . $spaces . ' = ' . $div);
        return (int)$div;
    }
    
    // This will read one header: value from the request header
    function getWebSocketHeader($buffer, &$lines, &$keys)
    {
        preg_match_all("/([a-zA-Z0-9\\-]*)(\\s)*:(\\s)*(.*)?\r\n/", $buffer, $headers);
        $lines = explode("\r\n", $buffer);
        $keys = array_combine($headers[1], $headers[4]);
     }
    
    // This is where the handshake gets done
    function handshake($peer)
    {
        $buffer = socket_read($peer, 4096, PHP_BINARY_READ);
        socket_getpeername($peer, $address, $port);
        $peerName = $address . ':' . $port;
        myLog('Got from: ' . $peerName . ': ' . $buffer);
        getWebSocketHeader($buffer, $lines, $keys);
        if (!isset($keys['Sec-WebSocket-Key1']) || !isset($keys['Sec-WebSocket-Key2'])) {
            myLog('Invalid websocket handshake for: ' . $peerName);
            return;
        }
        $key1 = getWebSocketKeyHash($keys['Sec-WebSocket-Key1']);
        $key2 = getWebSocketKeyHash($keys['Sec-WebSocket-Key2']);
        $code = array_pop($lines);
        // Process the result from both keys and form the response header
        $key = pack('N', $key1) . pack('N', $key2) . $code;
        myLog('1:|' . $key1 . '|- 2:|' . $key2 . '|3:|' . $code . '|4: ' . $key);
        $response = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n";
        $response .= "Upgrade: WebSocket\r\n";
        $response .= "Connection: Upgrade\r\n";
        $response .= "Sec-WebSocket-Origin: " . trim($keys['Origin']) . "\r\n";
        $response .= "Sec-WebSocket-Location: ws://" . trim($keys['Host']) . "/\r\n";
        $response .= "\r\n" . md5($key, true); // this is the actual response including the hash of the result of processing both keys
        myLog($response);
        socket_write($peer, $response);
    }
    
    // This is where you can send a frame (delimited by 0x00 and 0xFF)
    function send($peer, $message)
    {
        socket_write($peer, pack('c', (int)0) . utf8_encode($message) . pack('c', (int)255));
    }
    
    // This is where you receive a frame (delimited again by 0x00 and 0xFF)
    function receive($peer)
    {
        $buffer = socket_read($peer, 4096, PHP_BINARY_READ);
        if (empty($buffer)) {
            myLog('Error receiving from peer');
            return;
        }
        return substr($buffer, 1, -1);
    }
    
    // Now create a socket
    $socket = socket_create_listen(1026);
    $peer = socket_accept($socket);
    
    // Do the handshake and wait for an incoming message from the client
    handshake($peer);
    myLog('Got ' . receive($peer));
    
    // Respond!
    send($peer, 'hi there');
    socket_close($peer);
    socket_close($socket);
    

    编辑:

    这是一个非常基本的 html,可以在 chrome 中运行(至少是我的):

    <!DOCTYPE HTML>
    <html>
    <head>
    <script type="text/javascript">
    function WebSocketTest()
    {
      if ("WebSocket" in window)
      {
         // Let us open a web socket
         var ws = new WebSocket("ws://host:1026");
         ws.onopen = function()
         {
            // Web Socket is connected, send data using send()
            ws.send("Message to send");
            console.log('send');
         };
         ws.onmessage = function (evt)
         {
            var received_msg = evt.data;
            console.log(received_msg);
            var txt = document.createTextNode(received_msg);
            document.getElementById('messages').appendChild(txt);
         };
         ws.onclose = function()
         {
            // websocket is closed.
            console.log('close');
         };
      }
      else
      {
         // The browser doesn't support WebSocket
         alert("WebSocket NOT supported by your Browser!");
      }
    }
    </script>
    </head>
    <body>
    <div id="sse">
       <a href="javascript:WebSocketTest()">Run WebSocket</a>
    </div>
    <div id="messages">
    </div>
    </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 2016-03-30
      • 1970-01-01
      • 2013-03-28
      • 2017-12-21
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多