Websocket php服务器中的循环速度
Posted
技术标签:
【中文标题】Websocket php服务器中的循环速度【英文标题】:While loop speed in websocket php server 【发布时间】:2013-01-25 14:26:42 【问题描述】:我使用以下 websocket php 类作为我的服务器:PHPWebSocket。它在我所希望的各个方面都运行良好,但我遇到了一些问题。
我想以每 0.3 秒的速度更新已连接客户端(他们可以四处走动)的位置。我认为寻找 while 循环并在那里添加心跳事件是一件简单的事情,但在这里变得很棘手。
// server state functions
function wsStartServer($host, $port)
if (isset($this->wsRead[0])) return false;
if (!$this->wsRead[0] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))
return false;
if (!socket_set_option($this->wsRead[0], SOL_SOCKET, SO_REUSEADDR, 1))
socket_close($this->wsRead[0]);
return false;
if (!socket_bind($this->wsRead[0], $host, $port))
socket_close($this->wsRead[0]);
return false;
if (!socket_listen($this->wsRead[0], 10))
socket_close($this->wsRead[0]);
return false;
$this->log("Server starting");
$write = array();
$except = array();
$nextPingCheck = time() + 1;
while (isset($this->wsRead[0]))
$changed = $this->wsRead;
$result = socket_select($changed, $write, $except, 1);
**beat()**
if ($result === false)
socket_close($this->wsRead[0]);
return false;
elseif ($result > 0)
foreach ($changed as $clientID => $socket)
if ($clientID != 0)
// client socket changed
$buffer = '';
$bytes = @socket_recv($socket, $buffer, 4096, 0);
if ($bytes === false)
// error on recv, remove client socket (will check to send close frame)
$this->wsSendClientClose($clientID, self::WS_STATUS_PROTOCOL_ERROR);
elseif ($bytes > 0)
// process handshake or frame(s)
if (!$this->wsProcessClient($clientID, $buffer, $bytes))
$this->wsSendClientClose($clientID, self::WS_STATUS_PROTOCOL_ERROR);
else
// 0 bytes received from client, meaning the client closed the TCP connection
$this->wsRemoveClient($clientID);
else
// listen socket changed
$client = socket_accept($this->wsRead[0]);
if ($client !== false)
// fetch client IP as integer
$clientIP = '';
$result = socket_getpeername($client, $clientIP);
$clientIP = ip2long($clientIP);
if ($result !== false && $this->wsClientCount < self::WS_MAX_CLIENTS && (!isset($this->wsClientIPCount[$clientIP]) || $this->wsClientIPCount[$clientIP] < self::WS_MAX_CLIENTS_PER_IP))
$this->wsAddClient($client, $clientIP);
else
socket_close($client);
if (time() >= $nextPingCheck)
$this->wsCheckIdleClients();
$nextPingCheck = time() + 1;
return true; // returned when wsStopServer() is called
对我来说,似乎没有任何特定的计时器说它应该每秒只运行一次,但确实如此。我不是在谈论 ping 检查,即使我在 while (isset($this->wsRead[0])) 之后直接发出我的心跳调用,它也只会每秒触发一次,这让我完全被难住了。
我找错地方了吗? PHP 的 websocket 实现是否会减慢这个 while 循环?
【问题讨论】:
【参考方案1】:您的socket_select 呼叫有一秒钟的超时 - 这可能是您的延迟被引入的地方。如果您希望该调用是非阻塞的,您可以为该超时传递一个零。
【讨论】:
谢谢,我无法弄清楚 1 秒延迟的来源。我完全忽略了 socket_select 引入了自己的延迟这一事实。以上是关于Websocket php服务器中的循环速度的主要内容,如果未能解决你的问题,请参考以下文章