I am using php 7.4, created and set up websocket using Ratchet-PHP. Websocket is working good but the issue here is while injecting my event/notification inside the Websocket Hook function to send message to connected device.
My Socket Command Code:
use Ratchet\Server\IoServer;use Ratchet\WebSocket\WsServer;$server = IoServer::factory( new Ratchet\Http\HttpServer( new WsServer( new ChatFunctionClass() ) ), 6001, 0.0.0.0 ); $this->info("WebSocket server started on $port"); $server->run();
Chat Function Class: Haven't added all the function just the constructor and connection function hook only.
class ChatServer implements MessageComponentInterface{ private $clients; private $redisClient; public $userConnections; public function __construct() { $this->clients = new \SplObjectStorage; Redis::subscribe(['websocket-notifications'], function (string $message) { $this->sendMessage(json_decode($message)); }); } public function onOpen(ConnectionInterface $conn) { $querystring = $conn->httpRequest->getUri()->getQuery(); parse_str($querystring, $queryParams); $userId = $queryParams['user_id'] ?? null; if ($userId) { $this->clients->attach($conn, ['user_id' => $userId]); } echo "New connection: {$conn->resourceId} for user ID: {$userId}\n"; }
Scenerio:Websocket is running seperataly communicating with browser. Now when something changes through normal HTTP API I want to send notification to specific user/device ie Payment Info Changed/ Address Changed.
What I have tried so far:
i) I connected the websocket within the app and sent message with specific param, on that basis I sent notification to browser (working fine but doesn't seems to be good approach).
ii) Used Redis Pub/Sub, Subscribing to one channel inside the WebSocket hook function and publish message from API once published it send notification to associated user:Problem: Redis Sub function blocks the codes.
*Inside Websocket hook class constructor*Redis::subscribe(['websocket-notifications'], function (string $message) { $this->sendNotification(json_decode($message)); });*Publishing from HTTP API*Redis::publish('websocket-notifications', json_encode(['name' => 'Test','user_id' => '445454',"message" => "Address Changed by admin" ]));
iii) Tried using ZeroMQ but extension not working/maintained for php >= 7.3
iv) Tried running Redis Sub function/Queue with connection object asynchronously but no luck.BTW : I haven't tried Swoole yet.
It works fine in Node.js as it shares the global variable connection/connection list, so same object can be used in API, since PHP runs in separate process and no shareable resource, I don't know how to overcome this.
So is there any way I can fix this?