开发者

php websocket problem

开发者 https://www.devze.com 2023-03-26 00:35 出处:网络
I\'m new to web sockets.. i made my first web socket and i am having problems on running it now! here is the code of the socket

I'm new to web sockets.. i made my first web socket and i am having problems on running it now!

here is the code of the 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 connection开发者_运维问答s 
$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);

now how can i run this code?? i wrote on my xampp shell the following code:

php htdocs/socket/server.php -q

it displays:

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@

now how can i run it.. how can i send input to it and how can i use it with JavaScript??

i made a JavaScript code but it connect for a second and then disconnect...

here is the javascipt code:

$(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>​

please help me run this code and learn web sockets.. i really need to use them with my school project.


The socket_accept-function will block (wait) until a client connects to it. That's it's standard behavior.

But the functions you execute after you've connected your socket don't block (unless you tell them to). So you'll want to tell your script to wait until it can read from the Socket.

To do so, the socket_set_block-function is used. Also, you might want to check for any possible errors using the socket_last_error-function.

Although, I think Java or C are way bedder suited for using Sockets.


Write another PHP script which would connect to it.


you are not doing the handshake propertly.

from what you posted, you are dealing with the ietf-00 implementation ( https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-00 )

this is old and deprecated, the last one seems to be ietf-10 ( https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-10 ).

a very basic description of the handshake you need can be found here: http://en.wikipedia.org/wiki/WebSockets

(you can find in there the links to the newer and official specifications).

The important part in your case is this:

The Sec-WebSocket-Key1 and Sec-WebSocket-Key2 fields and the 8 bytes after the fields are random tokens which the server uses to construct a 16-byte token at the end of its handshake to prove that it has read the client's handshake.

The handshake is constructed by concatenating the numbers from the first key, and dividing by the number of spaces. This is then repeated for the second key. The two resulting numbers are concatenated with each other, and with the last 8 bytes after the fields.

The final result is an MD5 sum of the concatenated string.[7] The handshake looks like HTTP but actually isn't. It allows the server to interpret part of the handshake request as HTTP and then switch to WebSocket. Once established, WebSocket data frames can be sent back and forth between the client and the server in full-duplex mode. Text frames can be sent full-duplex, in either direction at the same time.

The data is minimally framed with just two bytes. Each frame starts with a 0x00 byte, ends with a 0xFF byte, and contains UTF-8 data in between. Binary frames are not supported yet in the API. WebSocket text frames use a terminator, while binary frames use a length prefix.

Now, some code (this will accept one connection, receive a message, and then send a response, just like a very basic and raw example to show how it can be done):

// 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);

EDIT:

this is a very basic html that works in chrome (mine at least):

<!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>
0

精彩评论

暂无评论...
验证码 换一张
取 消