【发布时间】:2017-08-24 21:51:21
【问题描述】:
我目前正在开发一个 PHP 应用程序,该应用程序将使用一些 websocket 连接与另一个服务通信。
为了与这个 websocket 服务通信,我们使用 Ratchet - 这是一个基于 react PHP 的 PHP 库。
这段代码需要发送和响应几个请求,然后将信息返回给“主线程”。
示例流程:
HTTP 请求 -> 控制器 -> 启动一个打开 websocket 客户端的服务 -> websocket 客户端正在与服务器通信 -> 一旦完成,它应该将结果返回给控制器代码 -> 控制器输出给用户
我遇到的问题是我不熟悉 Reactive PHP 并且不确定如何处理。
我试过了;
$service = new WebsocketService();
$startTimer = time();
$service->getList(44);
while($service->getResponse() == null) {
usleep(500);
if (time() > $startTimer + 10) {
continue; //Timeout on 10 seconds
}
}
var_dump($service->getResponse());
一旦完成,服务代码会将其“响应”变量设置为 null 以外的值。这显然失败了,因为 sleep 方法正在阻塞线程。同样没有,似乎 while 循环阻塞了 I/O 并且响应式代码失败了。
解决方案是打开一个新线程并在那里运行 websocket 代码,但我不会对此感到满意。
我觉得我需要围绕 websocket 进程实现某种“观察者”,但我不知道该怎么做。
我们的 Websocket 服务客户端代码如下所示;
private $response = null;
/**
* @return null|object
*/
public function getResponse() {
return $this->response;
}
public function getList($accountId) {
$this->response = null;
\Ratchet\Client\connect('ws://192.168.56.1:8080')->then(function(\Ratchet\Client\WebSocket $conn) use ($accountId) {
$login = new \stdClass();
$login->action = 'login';
$conn->on('message', function($msg) use ($conn, $login, $accountId) {
try {
$response = json_decode($msg);
if ($response->result_id == 100) {
//Succesfully logged in to websocket server
//Do our request now.
$message = new \stdClass();
$message->target = 'test';
$conn->send(json_encode($message));
}
if (isset($response->reply) && $response->reply == 'list') {
$this->response = $response; //This is the content I need returned in the controller
$conn->close(); //Dont need it anymore
}
} catch (\Exception $e) {
echo 'response exception!';
//Do nothing for now
}
});
$conn->send(json_encode($login));
}, function ($e) {
echo "Could not connect: {$e->getMessage()}\n";
});
}
这样运行代码也行不通;
$service = new WebsocketService();
$service->getList(44);
echo 'Test';
var_dump($service->getResponse());
因为“测试”回显在我从 websocket 服务器得到响应之前就出现了。
请赐教!我不确定要搜索什么。
【问题讨论】:
标签: php multithreading reactive-programming reactphp