欢迎来到 SiteSMO | 思默AI智能问答平台!
注册或点击登录代表您同意《SiteSMO网络服务安全协议》
提示信息
请打开微信扫码登录
返回列表

php实现一个websocket服务器,包括消息发送和接收

举报
263阅读 | 0人回复 | 2023-04-09 15:34:05

本帖由 宝贝熊 ... 发布,如有侵权联系删除 IP属地:上海

以下是一个简单的PHP WebSocket服务器的实现。它可以监听来自客户端的连接,并处理消息发送和接收:

class WebSocket
{
    private $sockets = [];
    private $clients = [];

    public function __construct($host, $port)
    {
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
        socket_bind($socket, $host, $port);
        socket_listen($socket);
        $this->sockets[] = $socket;
        echo "Server started\nListening on: $host:$port\n";

        while (true) {
            $this->handleSockets();
        }
    }

    private function handleSockets()
    {
        $readSockets = $this->sockets;
        $writeSockets = [];
        $exceptSockets = null;

        socket_select($readSockets, $writeSockets, $exceptSockets, null);

        foreach ($readSockets as $socket) {
            if ($socket == $this->sockets[0]) {
                // new connection
                $clientSocket = socket_accept($socket);
                $this->sockets[] = $clientSocket;
                $this->clients[] = ['socket' => $clientSocket, 'handshake' => false];
                echo "New client connected\n";
            } else {
                $client = $this->getClientBySocket($socket);
                if (!$client['handshake']) {
                    // handshake
                    $this->doHandshake($client, socket_read($socket, 1024));
                } else {
                    // handle message
                    $message = socket_read($socket, 1024);
                    if ($message === "") {
                        // client disconnected
                        $this->disconnectClient($client);
                    } else {
                        $this->sendToAllClients($message);
                    }
                }
            }
        }
    }

    private function doHandshake(&$client, $data)
    {
        $headers = [];
        $lines = preg_split("/\r\n/", $data);

        foreach ($lines as $line) {
            if (strpos($line, ':') !== false) {
                list($key, $value) = explode(':', $line, 2);
                $headers[strtolower(trim($key))] = trim($value);
            }
        }

        $secKey = $headers['sec-websocket-key'];
        $secAccept = base64_encode(sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));

        $response = "HTTP/1.1 101 Switching Protocols\r\n";
        $response .= "Upgrade: websocket\r\n";
        $response .= "Connection: Upgrade\r\n";
        $response .= "Sec-WebSocket-Accept: $secAccept\r\n\r\n";

        socket_write($client['socket'], $response, strlen($response));

        $client['handshake'] = true;
    }

    private function disconnectClient(&$client)
    {
        $index = array_search($client, $this->clients);
        socket_close($client['socket']);
        unset($this->clients[$index]);
        $this->clients = array_values($this->clients);
        echo "Client disconnected\n";
    }

    private function getClientBySocket($socket)
    {
        foreach ($this->clients as &$client) {
            if ($socket == $client['socket']) {
                return $client;
            }
        }
    }

    private function sendToAllClients($message)
    {
        foreach ($this->clients as &$client) {
            socket_write($client['socket'], $message, strlen($message));
        }
    }
}

new WebSocket('localhost', 8888);

使用:

启动服务器:

php websocket.php

在浏览器中打开WebSocket客户端,连接服务器并发送消息:

var socket = new WebSocket('ws://localhost:8888');

socket.onopen = function(e) {
    console.log('WebSocket connected');
    socket.send('Hello WebSocket');
};

socket.onmessage = function(e) {
    console.log('Received message:', e.data);
};
复制
1
0

注:避免重复,不要就相同的标题进行反复追问。

回答共0个
回复禁止带推广链接、违法词及灌水,违规将封禁账号!!
您需要登录后才可以回复 注册 / 登录
每个账号仅有一次回答机会!
取消
提示信息
请选择举报理由
我要回答