what i’m trying is connect the client [webSocket] with PHP server socket my server socket will accept the socket from client, and fetch the Request headers,
after receiving the Request, i sent back handshake [response] But the status for webSocket [client] is pending and never get the response
JS code:
const URL = "ws://localhost:8050"; var socket = new WebSocket(URL); socket.onopen = function() { console.log("Socket is openned!"); } socket.onmessage = function() { console.log("new message!"); }
and my PHP server Socket:
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if (socket_bind($this->socket, self::ADDRESS, self::PORT) === false) { throw new Exception("Could not bind socket at address ${self::ADDRESS}, port ${self::PORT}"); } if (socket_listen($this->socket) === false) { throw new Exception("Could not listen!!"); } $running = true; $clients = []; while ($running) { if (count($clients) < 2) { $accept = socket_accept($this->socket); // handshake $this->handshake($accept); $clients[] = $accept; sleep(2); continue; } }
handshake function:
private function handshake($client) { if ($client instanceof Socket || is_resource($client)) { echo "== Client is Vaild ==n"; } // client sent the Request $read = socket_read($client, 2048); if ($read === false) { throw new Exception("Could not Read!!"); } // headers if (preg_match("/Sec-WebSocket-Key: (.*)/", $read, $matches)){ $key = base64_encode(hash("sha1",$matches[1]."258EAFA5-E914-47DA-95CA-C5AB0DC85B11")); $response_header = "HTTP/1.1 101 Switching Protocolsrn". "Upgrade: websocketrn". "Connection: Upgradern". "Sec-WebSocket-Accept: $keyrn"; // send the response $bytes_sent = socket_write($client, $response_header, strlen($response_header)); if ($bytes_sent === false) { echo "n====== Cannot send the handshake ==========n"; } elseif ($bytes_sent > 0) { // ------- sent around 155 bytes ----------- // echo "n====== handshake has been sent [". $bytes_sent ."bytes] ==========n"; } } }
After sending the response, the client still in pending status, and the connection not openned.
Thank you.
The Request From Client:
GET / HTTP/1.1 Host: localhost:8050 Connection: Upgrade Pragma: no-cache Cache-Control: no-cache User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Upgrade: websocket Origin: http://localhost Sec-WebSocket-Version: 13 Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9,ar;q=0.8 Cookie: _ga=GA1.1.213058296.1602471332; __atuvc=1%7C52%2C1%7C3 Sec-WebSocket-Key: UmjWLRlhTXqM1rF6kSaVhQ== Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
what i’m trying is sending back the response:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: NmQwYjVlY2VhMTQzMzUyYjFiNWMwZmU4Y2E3NmFjZTc4ZDc4N2I2Yw==
UPDATE:
I fixed the Sec-WebSocket-Accept key by using sha1(…, binary = true) before base64.
End my Response i added
rn
to end the header response.
Now i’m getting error: webSocket connection http://host:port failed.
Advertisement
Answer
It’s done, the problem was Sec-WebSocket-Accept
key, it needed to be trim(key)