[英]php server socket & webSocket HTML5 client
我正在尝试的是将客户端 [webSocket] 与 PHP 服务器套接字连接,我的服务器套接字将接受来自客户端的套接字,并获取请求标头,
收到请求后,我发回握手 [response] 但是 webSocket [client] 的状态是 pending 并且从未得到响应
JS代码:
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!");
}
和我的 PHP 服务器套接字:
$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;
}
}
握手 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 Protocols\r\n".
"Upgrade: websocket\r\n".
"Connection: Upgrade\r\n".
"Sec-WebSocket-Accept: $key\r\n";
// 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";
}
}
}
发送响应后,客户端仍处于挂起状态,连接未打开。
谢谢。
来自客户的请求:
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
我正在尝试发回响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: NmQwYjVlY2VhMTQzMzUyYjFiNWMwZmU4Y2E3NmFjZTc4ZDc4N2I2Yw==
更新:
我在 base64 之前使用 sha1(..., binary = true) 修复了Sec-WebSocket-Accept密钥。
结束我的回复 我添加了\r\n
以结束 header 回复。
现在我收到错误:webSocket 连接 http://host:port 失败。
搞定了,问题是Sec-WebSocket-Accept
key,需要trim(key)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.