Search code examples
phpsocketsratchet

How to handle sockets in PHP


I am using Ratchett to create sockets on my web server with PHP.

Currently I have A - the server, B - a device looking for a change on a database(in A) and C - a device making the change on the database(in A) with a curl request.

Currently when C makes the change I store the change in the database on A. Mean while B is checking every second with A through a socket whether there is an item is in the database by sending a request to A in which A returns a response. This is a waist of Bs resources. I need a way for when C makes a change for the socket to update B.

This is the code for the socket:

<?php
namespace Notify;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

require "/NAS/notify/db.php";

class Note implements MessageComponentInterface { 
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        $this->clients->attach($conn);
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        $stack = array(); 
        foreach ($this->clients as $client) {
            if ($from === $client) { //current client only
                $query = getNotifications($msg);
                if($query){
                    while($row = mysqli_fetch_assoc($query)){
                        array_push($stack, $row);
                        deleteNotification($row['id'], $msg);
                    }
                    $client->send(json_encode($stack));
                }
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        $this->clients->detach($conn);
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        $conn->close();
    }
}

Where getNotifications() gets the change in the database and deleteNotification() deletes it.


Ideas:

  1. I have thought about storing the $client object in a database so that when C makes the change it can use $client->send() but I do not think that is possible?
  2. I could have a while(true) loop with the $query = getNotifications($msg); code inside - awful for A.

Do you have any other ideas? Or ways to implement the above.


Solution

  • Consider using a publish-subscribe pattern where a client looking for updates to an object "X" subscribes to a topic and then have the server publish on that topic. Ratchet can handle this with WAMPv1: http://socketo.me/docs/wamp or you could use Thruway which is WAMPv2 built on top of ratchet.