0

我正在尝试设置一个 WebSocket 应用程序,但我陷入了以下困境。接受套接字后,我按预期收到了客户端的标头,但是当我尝试将升级发送回时socket_write()会引发警告:

Warning: socket_write(): unable to write to socket [10038]: An operation was attempted on something that is not a socket

这发生在以下代码中:

var_dump($this->socket); //output: resource(2) of type (Socket)
socket_write($this->socket, $upgrade);

这发生在 pthreads 上下文中。
PHP向我抛出此警告的可能原因是什么?

完整代码:

public function handshake($headers)
{
    Main::console($headers);
    Main::console("Getting client WebSocket version...");
    Main::console("Headers: \r\n\r\n".$headers);
    if(preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $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: (.*)\r\n/", $headers, $match))
            $host = $match[1];
        if(preg_match("/Origin: (.*)\r\n/", $headers, $match))
            $origin = $match[1];
        if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match))
            $key = $match[1];

        Main::console("Client headers are:\r\n\r\n".
                        "- Root: ".$root."\r\n".
                        "- Host: ".$host."\r\n".
                        "- Origin: ".$origin."\r\n".
                        "- Sec-WebSocket-Key: ".$key."\n");

        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\r\n".
                   "Upgrade: websocket\r\n".
                   "Connection: Upgrade\r\n".
                   "Sec-WebSocket-Accept: $acceptKey".
                   "\r\n\r\n";

        Main::console("Sending this response to the client #{$this->getId()}:\r\n\r\n".$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}");
        }
    }
}

}

4

1 回答 1

1

尝试socket_last_error()socket_strerror()获取更多信息。如果这没有帮助,请向我们展示如何创建套接字。来源:http ://www.php.net/manual/en/function.socket-last-error.php

于 2013-05-23T09:24:22.343 回答