Tengo problemas para implementar un socket server con PHP, he realizado pruebas con diferentes clientes sin problemas, pero cuando uso websocket en Chrome o Firefox las cadenas se corrompen por alguna razón que desconozco, sospecho que el problema se encuentra en el “apretón de manos” agradeceré cualquier ayuda porque ya estoy dando vueltas en circulo.
Aquí dejo el código esperando su ayuda, gracias
server socket
Código PHP:
Ver original<?php
class MySocketServer {
protected $socket;
protected $clients = [];
protected $changed;
public function __construct($host, $port) {
//bind socket to specified host
//listen to port
}
public function __destruct() {
foreach ($this->clients as $client) {
}
}
public function run() {
// create a list of all the clients that will be connected to us..
// add the listening socket to this list
$this->clients = array($this->socket); while (true) {
// create a copy, so $clients doesn't get modified by socket_select()
// reset changed
$this->changed = $this->clients;
// get a list of all the clients that have data to be read from
// if there are no clients with data, go to next iteration
$write = $except = NULL;
$this->checkNewClients();
$this->checkMessageRecieved();
$this->checkDisconnect();
}
}
}
private function checkNewClients() {
$this->log("checkNewClients...");
// check if there is a client trying to connect
if (in_array($this->socket, $this->changed)) { // accept the client, and add him to the $clients array
// $header = socket_read($newsock, 2048, PHP_NORMAL_READ);
// @socket_recv($newsock, $header, 1024, 0);
if ((int
) @socket_recv($newsock, $header, 2048, MSG_DONTWAIT
) > 0) { $handshake = $this->handshake($header);
$this->log("handshake: " . $handshake); }
$this->log("There are " . (count($this->clients) - 1) . " client(s) connected to the server\n"); $this->log("New client connected: " . $ip);
// remove the listening socket from the clients-with-data array
unset($this->changed[$key]); }
}
private function checkMessageRecieved() {
foreach ($this->changed as $key => $socket) {
$buffer = null;
$this->log(trim("Client Message: " . $buffer)); unset($this->changed[$key]); break;
}
}
}
private function checkDisconnect() {
foreach ($this->changed as $changed_socket) {
$buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ
); if ($buf !== false) {
continue;
}
// remove client for $clients array
$found_socket = array_search($changed_socket, $this->clients); unset($this->clients[$found_socket]); $this->log('client ' . $ip . ' has disconnected'); }
}
function handshake($header) {
$handshake = '';
$this->log('header ' . $header); if (preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $header, $match)) { $version = $match[1];
} else {
$this->log("The client doesn't support WebSocket"); }
if ($version == 13) {
if (preg_match("/GET (.*) HTTP/", $header, $match)) $root = $match[1];
if (preg_match("/Host: (.*)\r\n/", $header, $match)) $host = $match[1];
if (preg_match("/Origin: (.*)\r\n/", $header, $match)) $origin = $match[1];
if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $header, $match)) $key = $match[1];
$acceptKey = $key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
$handshake .= "HTTP/1.1 101 Switching Protocols\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"Sec-WebSocket-Accept: $acceptKey" .
"\r\n\r\n";
} else {
$this->log("WebSocket version 13 required (the client supports version {$version})"); }
return $handshake;
}
private function sendMessage($msg) {
foreach ($this->clients as $client) {
}
return true;
}
private function log($msg) { echo "\r\n$msg\r\n";
}
}
require_once ('config.php');
(new MySocketServer($host, $port))->run();
websocket
Código PHP:
Ver original<?php require_once ('config.php'); ?>
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
var websocket;
window.onload = function () {
websocket = new WebSocket('<?php echo "ws://{$host}:{$port}"; ?>');
websocket.onopen = function (evt) {
console.log("connected..");
};
websocket.onclose = function (evt) {
console.log("websocket close");
};
websocket.onmessage = function (evt) {
console.log(event.data);
};
websocket.onerror = function (evt) {
console.log(event.data);
};
document.querySelector("#send").addEventListener("click", function () {
websocket.send(document.querySelector("#message").value);
});
};
</script>
<h2>WebSocket Test</h2>
<input type="text" id="message" name="message" value="" />
<input type="button" id="send" name="send" value="Enviar" />
Obtengo esta salida, como pueden ver el mensaje enviado con el navegador no llega correctamente.