I'm trying to set up a WebSocket application, but I'm stuck at the following.
After accepting the socket I received the client's headers as expected, but when I try to send the upgrade back socket_write()
throws a warning:
Warning: socket_write(): unable to write to socket [10038]: An operation was attempted on something that is not a socket
This happens in the following piece of code:
var_dump($this->socket); //output: resource(2) of type (Socket)
socket_write($this->socket, $upgrade);
This happens inside a pthreads context.
What are possible reasons PHP is throwing me this warning?
The full code:
public function handshake($headers)
{
Main::console($headers);
Main::console("Getting client WebSocket version...");
Main::console("Headers:
".$headers);
if(preg_match("/Sec-WebSocket-Version: (.*)
/", $headers, $match))
$version = $match[1];
else {
Main::console("The client doesn't support WebSocket");
return false;
}
Main::console("Client WebSocket version is {$version}, (required: 13)");
if($version == 13) {
// Extract header variables
Main::console("Getting headers...");
if(preg_match("/GET (.*) HTTP/", $headers, $match))
$root = $match[1];
if(preg_match("/Host: (.*)
/", $headers, $match))
$host = $match[1];
if(preg_match("/Origin: (.*)
/", $headers, $match))
$origin = $match[1];
if(preg_match("/Sec-WebSocket-Key: (.*)
/", $headers, $match))
$key = $match[1];
Main::console("Client headers are:
".
"- Root: ".$root."
".
"- Host: ".$host."
".
"- Origin: ".$origin."
".
"- Sec-WebSocket-Key: ".$key."
");
Main::console("Generating Sec-WebSocket-Accept key...");
$acceptKey = $key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
$acceptKey = base64_encode(sha1($acceptKey, true));
$upgrade = "HTTP/1.1 101 Switching Protocols
".
"Upgrade: websocket
".
"Connection: Upgrade
".
"Sec-WebSocket-Accept: $acceptKey".
"
";
Main::console("Sending this response to the client #{$this->getId()}:
".$upgrade);
var_dump($this->socket);
socket_write($this->socket, $upgrade, strlen($upgrade));
$this->setHandshake(true);
Main::console("Handshake is successfully done!");
return true;
}
else {
Main::console("WebSocket version 13 required (the client supports version {$version})");
return false;
}
}
public function run()
{
while($this->alive)
{
$bytes = @socket_recv($this->socket, $buffer, 4096, MSG_WAITALL);
if ($buffer)
{
if(!$this->handshake)
{
$this->handshake($buffer);
} else {
Main::console("Client {$this->getID()} says {$buffer}");
}
}
}
}