【问题标题】:Wait for socket_write to complete before writing again等待 socket_write 完成后再写入
【发布时间】:2016-11-04 18:36:37
【问题描述】:

我需要将一些数据从 PHP 服务器发送到 Node 服务器。

这是我目前在 PHP 方面的简化版本:

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, '127.0.0.1', '3000');
socket_write($socket, "Hello World", 11);
socket_close($socket);

运行此代码成功将消息发送到我的节点服务器并输出。

但是,我需要将多个消息发送回套接字。我实际上需要发送数千个回复。但是,如果我要在这样的循环中调用 socket_write() 函数:

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, '127.0.0.1', '3000');
for($i=0;$i<1000;$i++){
    socket_write($socket, "Hello World", 11);
}
socket_close($socket);

它似乎将所有数据附加在一起并在脚本末尾一次性发送。我需要实时发回数据。有什么办法可以在 PHP 中做到这一点?

【问题讨论】:

  • 你的socket成功发送到哪里?如何确保资源可用?发送,取一条成功的消息,再次发送。如果您不需要答案,为什么要使用 socket ?用作静态文件。
  • @dsgdfg 我不需要收到节点服务器收到数据的确认。如果与套接字的连接失败,我会抛出异常
  • @dsgdfg 你认为我应该让节点服务器返回成功响应吗?也许这是我告诉 PHP 进入下一个循环迭代很酷的唯一方式

标签: php node.js sockets


【解决方案1】:

在查看了许多 PHP 套接字库后,我注意到几乎所有这些库都只是在发送套接字后实现了 usleep(1000000)。我不确定这是否是最好的方法,但由于 PHP 的限制,这可能是唯一的方法。

最后,我决定存储数据最后一次写入套接字的时间。然后,计算从那时起经过的时间并从 1000000 微秒中减去。这样,脚本就不会等待超过必要的时间。

public function send(array $payload){
    $json = json_encode($payload);
    $write = socket_write($this->socket, $json, strlen($json);
    $sleep_time = 1000000 - (microtime(true) - $this->last_sent);
    if($sleep_time > 0) usleep($sleep_time);
    $this->last_sent = microtime(true);
    return $write !== false ? true : false;
}

【讨论】:

  • 我也遇到了socket_write 似乎将多个 JSON 对象附加在一起的问题。你有没有弄清楚为什么会发生这种情况?正在实施usleep(1000000) 解决方案,一切正常。
  • @Stephan-v 我的模糊猜测是,当套接字被发送时,如果仍在发送,它们最终会变得混乱在一起。我实际上写了一个使用上述解决方案的小类:github.com/danjohnson95/PHP-Socket-Emitter
  • 好东西,谢谢。它将帮助我完成我的项目。我仍然想知道究竟是什么原因造成的:)
  • @Stephan-v 我也是。今天我会做更多的研究,然后带着我的发现回到你身边。祝你的项目好运
猜你喜欢
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 2013-04-25
  • 2019-11-01
  • 2013-03-22
  • 2021-05-06
  • 2021-05-21
相关资源
最近更新 更多