Good day to all. I want to write a simple WebSocket server in php and encountered the following problem: When shaking hands, I send a response from the server, according to the specification

header('Content-Type: text/html; charset=utf-8'); set_time_limit(0); ob_implicit_flush(); $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_bind($server, '127.0.0.1', 8131); socket_listen($server, 100); socket_set_nonblock($server); $sockets = array(); while(true) { $sock = socket_accept($server); if ($sock !== false) $sockets[] = array($sock, false); if (!empty($sockets)) foreach($sockets as $sock) { $data = @socket_read($sock[0], 1024); if ($data !== false) if ($sock[1] == false) $sock[1] = handshake($sock[0], $data); else обработка($sock[0], $data); } } function handshake($sock, $data) { $len = strlen('Sec-WebSocket-Key: '); $pos1 = strpos($data, 'Sec-WebSocket-Key:') + $len; $pos2 = strpos($data, "\r\n", $pos1 + 1); $Sec_WebSocket_Key = substr($data, $pos1, $pos2 - $pos1); echo 'KEY: '.$Sec_WebSocket_Key.'<br>'; $SecWebSocketAccept = base64_encode( sha1($Sec_WebSocket_Key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true) ); $answer = "HTTP/1.1 101 Switching Protocols\r\n". "Upgrade: websocket\r\n". "Connection: Upgrade\r\n". "Sec-WebSocket-Accept: ".$SecWebSocketAccept."\r\n\r\n"; socket_write($sock, $answer, strlen($answer)); echo '<br>Ушло: '.$answer.'!<br><br><br>'; return true; } function обработка($sock, $data) { echo "Пришли данные: ".$data."<br>"; socket_write($sock, $data." answer"); } 

Slightly perverted places. I retrieve the key from the request correctly. SecWebsocketAccept coincides with an example from the documentation and is encoded, like, right. When the response from the server comes to the client, it will be loaded. Those. the page is loaded and it does not stop. It does not issue errors and none of the events attached to the web socket does not work. (if you change something in the server response, then the browser logs will either give an incorrect key or extra fields).

 var socket = new WebSocket("ws://socket-example.ru:8131/index.php"); socket.open = function() { alert("Соединение установлено"); } socket.onerror = function() { alert("Ошибка при подключении сокета"); } socket.onclose = function(e) { alert("Соединение закрыто." + e.message); print(e);} socket.onmessage = function(e) { alert("Получено сообщение: " + e.data); } 

I don’t understand why the browser does not accept the header sent by the server and doesn’t want to switch from HTTP to WebSocket. The page is loaded and that's it. It helped terminate the code with the socket_close (...) command; But then it shows on the client that the connection is broken.

You can also answer how in the HTTP protocol the browser finds out that the message has ended, except for breaking the connection? For example, if a completely blank page comes in, consisting only of the HTTP header. I know that they use Content-Length: 0, but are there any other ways?

The above server code should be new and more understandable, there is still old one (almost all tests are on it) - it can also give something to understand

 header('Content-Type: text/html; charset=utf-8'); $answer = "HTTP/1.1 101 Switching Protocols\r\n". "Upgrade: websocket\r\n". "Connection: Upgrade\r\n". //"Content-Length: 0\r\n". "Sec-WebSocket-Accept: "; set_time_limit(17); ob_implicit_flush(); $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_bind($server, '127.0.0.1', 8131); socket_listen($server, 100);// Socket listening... OK //socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1); echo "Сервер запущен!<br>"; $sock = NULL; while(true) { $sock = socket_accept($server); echo "Есть подключение клиента!<br>"; $data = socket_read($sock, 1024); echo "Пришло: ".$data."<br><br>"; /*$data_arr = explode(' ', $data); foreach ($data_arr as $val) echo $val.'<br>';*/ $len__1 = strlen('Sec-WebSocket-Key: '); $pos1 = strpos($data, 'Sec-WebSocket-Key:') + $len__1; $pos2 = strpos($data, "\r\n", $pos1 + 1); $Sec_WebSocket_Key = substr($data, $pos1, $pos2 - $pos1); echo 'KEY: '.$Sec_WebSocket_Key.'<br>'; $SecWebSocketAccept = base64_encode( sha1($Sec_WebSocket_Key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true) ); $answ = $answer.$SecWebSocketAccept."\r\n\r\n";//\r\nSec-WebSocket-Protocol: chat socket_write($sock, $answ, strlen($answ)); echo 'Ушло:<br>'.$answ.'!<br><br><br>'; //socket_close($sock); $data = socket_read($sock, 1024); echo "Считал: ".$data."<br>"; socket_write($sock, bindec(0)."myMSG".decbin(255)); while(true); if ($data == 333) { echo "Сокет закрыт!<br>"; break; } } socket_close($server); 
  • How do you run this code? - andreymal
  • ru.stackoverflow.com/questions/884843/… my answer in another question, about how the browser knows the end of the message - Zergatul
  • andreymal, I launch the php script by calling the specified link in the browser ( socket-example.ru ). Client - double click on the html file in the same browser. - Dmitry
  • Zergatul, Thank you. And yet - do not tell me which of these described methods is happening in my case, otherwise 2 are at least suitable ... - Dmitry

0