Sockets with PHP and Node
Tags: php
Published: 2020-01-28 09:45:23

---
title: Sockets with PHP and Node
published: true
tags: php
canonical_url: 
---

I was looking to implement real time notifications system via sockets without having to use any third party services such as [Pusher](https://pusher.com/), etc. I just wanted to be able to send notifications from PHP side to the client and instantly show them on the web application similar to Facebook notifications.

First I came across [ratchet](http://socketo.me/) library, it worked great but problem emerged when setting it up on secure connection (https) on my host (siteground), tried apache proxy module and everything else told on the internet but to no avail (it seems siteground has problem with ratchet on https) so in the end I had to drop ratchet.

Then I thought of using [socket.io](https://socket.io/) with Node+PHP and with my research I came across [elephant.io](https://github.com/Wisembly/elephant.io) library (though it isn't updated recently) and this one worked wonderfully well both on non-secure and secure protocols allowing us to send and receive messages from PHP with node-based server.

Here are the steps that I followed to get my notification system working.

**Install elephant.io**

For your PHP application, install `elephant.io` via composer:

```
composer require wisembly/elephant.io
```

**Install Node Dependencies**

Create a directory in your project root and under it create a file named `package.json` with these contents:

```
{
    "name": "elephantIO_example_emitter",
    "version": "3.0.0",
    "main": "server.js",

    "scripts": {
        "start": "supervisor --debug server.js"
    },

    "dependencies": {
        "socket.io": "~1",
        "winston": "*"
    }
}
```

On newly created directory run command `npm install --save`. This will install `socket.io` and logger library.

In same newly created directory, create a file `server.js` with these contents:

```
var server = require('http').createServer(),
    io = require('socket.io')(server),
    logger = require('winston'),
    port = 1337;

// Logger config
logger.remove(logger.transports.Console);
logger.add(logger.transports.Console, { colorize: true, timestamp: true });
logger.info('SocketIO > listening on port ' + port);

io.on('connection', function (socket){
    var nb = 0;

    logger.info('SocketIO > Connected socket ' + socket.id);

    socket.on('broadcast', function (message) {
        ++nb;
        logger.info('ElephantIO broadcast > ' + JSON.stringify(message));

        // send to all connected clients
        io.sockets.emit("broadcast", message);
    });

    socket.on('disconnect', function () {
        logger.info('SocketIO : Received ' + nb + ' messages');
        logger.info('SocketIO > Disconnected socket ' + socket.id);
    });
});

server.listen(port);
```

Run `server.js` file through node by typing `node server.js`, you should see message that server has started on specified port.

**Client Side**

Put following javascript code in your application's page/footer:

```
<script src='//cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.4/socket.io.min.js'></script>

<script>
var socket = io.connect('//127.0.0.1:1337');

socket.on('connect', function () {
    console.log('connected');

    socket.on('broadcast', function (data) {
        //console.log(data);
        //socket.emit("broadcast", data);
        alert(data.text);
    });

    socket.on('disconnect', function () {
        console.log('disconnected');
    });
});
</script>
```

**Sending Notification from PHP**

Here is how you can send a message to all connected clients:

```
require __DIR__. '/vendor/autoload.php';

use ElephantIO\Client;
use ElephantIO\Engine\SocketIO\Version1X;

$client = new Client(new Version1X('//127.0.0.1:1337'));

$client->initialize();
// send message to connected clients
$client->emit('broadcast', ['type' => 'notification', 'text' => 'Hello There!']);
$client->close();
```

and that's all there is to it.

**Installing and Running Node on Production Site**

I was on `CentOSv6` and I installed node by following [this guide](https://www.a2hosting.com/kb/installable-applications/manual-installations/installing-node-js-on-managed-hosting-accounts). Then I created simple php file that will be run by cron so that node server is automatically started/restarted if it is not running:

```
$nodePath = 'your node binary path here';
$filePath = 'your server.js file path';
shell_exec($nodePath . ' ' . $filePath);
```

and then specify that file in cron to run at your specified time intervals.

**Important Notes**

- I was having bit of issue getting node path from PHP script where I initially installed it so I copied the nodejs folder to my `public_html` folder (app's root).
- On production site, I had to type actual server IP rather than `127.0.0.1` on client side code eg instead of `var socket = io.connect('//127.0.0.1:1337');`, it has to be `var socket = io.connect('//SERVER_IP_HERE:1337');`
- If you are having issue getting it to work on https, check out [issues section](https://github.com/Wisembly/elephant.io/issues?utf8=%E2%9C%93&q=) to fix it.
- Check out **examples** folder of `elephant.io` to know how to send or receive messages both from PHP as well as Javascript.
 ![](http://feeds.feedburner.com/~r/codeinphpfeed/~4/o1kQYL067ec)