Forem

Sarfraz Ahmed
Sarfraz Ahmed

Posted on • Originally published at codeinphp.github.io on

3 1

Sockets with PHP and Node

I was looking to implement real time notifications system via sockets without having to use any third party services such as Pusher, 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 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 with Node+PHP and with my research I came across 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
Enter fullscreen mode Exit fullscreen mode

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": "*"
    }
}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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. 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);
Enter fullscreen mode Exit fullscreen mode

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 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.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (1)

Collapse
 
up_1 profile image
UP • Edited

i'm trying to emit an event from a controller with elephant io by using version2x but i get a version1x error.
Error: UnexpectedValueException: The server returned an unexpected value. Expected "HTTP/1.1 101", had "HTTP/1.1 400" in vendor/wisembly/elephant.io/src/Engine/SocketIO/Version1X.php:266

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay