Has anyone worked with websockets?
I have been working, unsuccessfully, on a project to update views via websockets, but I haven’t been able to get the connected clients to communicate with each other.
The websocket server launches without any issues.
Websockets Server
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$server = IoServer::factory(
new HttpServer(
new WsServer(
SocketClass::getInstance() //trying to use singleton approach
)
),
8080
);
echo 'Running websocket server now...';
$server->run();
}
The client connection works fine and connects to the corresponding session.
var socket = new WebSocket('ws://127.0.0.1:8080');
socket.onopen = function(event) {
console.log('Success connection');
socket.send(JSON.stringify({
action: 'subscribe',
event_id: currentEventId }));
};
The problem arises when executing a component function, which should, in addition to executing the logic of my project, send the notification to the clients. However, it creates a new instance despite my attempts to use the Singleton pattern
public function onMessageIt()
{
//do my database work and business logic....
// Sending update to websocket
$wsHandler = SocketClass::getInstance(); //In this momment, a new instance is created
Log::debug("calling to bradcastUpdate. Instance ID: " . spl_object_id($wsHandler)); //yes, a new instance ID is created
$wsHandler->broadcastUpdate(); //trying to sending the update to all clients
}
This is the websocket class
private function __construct()
{
$this->clients = new \SplObjectStorage;
}
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
}
public function onMessage(ConnectionInterface $from, $msg)
{
$data = json_decode($msg, true);
if (isset($data['action']) && $data['action'] === 'subscribe') {
$from->event_id = $data['event_id'];
} else {
Log::debug("Unknown message from {$from->resourceId}: $msg")
}
}
public function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e)
{
$conn->close();
}
public function broadcastUpdate($eventId)
{
Log::debug("Broadcasting for : " . count($this->clients)); //this is always one, because in this point, each client is working with it's own connection
$totalClients = count($this->clients);
}
I have tried to manage it using the Singleton documentation, but I don’t fully understand how the generation and reuse of a class works.
Thanks all for your help