Back

Simple implementation of Soketi with php

Have you ever noticed that you receive a notification as soon as someone likes your post and that happens in realtime without you having to refresh the website or go to notification centre? If you've placed food orders online or booked an Uber ride you'll see the latest status of your order without you having to refresh the page. The HTTP protocol that is the protocol used by webpages follows the pull method i.e. you'll need to give instructions to the server to pull the data back. This can be triggered either by you clicking a button, for example, or refreshing the page. You could also write a script in javascript using setInterval function and pull the results from the server every couple of minutes. SetInterval is running the javascript code in your users' browser and refreshing the page to see how many likes you've got isn't the best way to see the notifications.

Here's where websockets come into play. Wiki: "WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection". What this means is that it'll allow you to have a 2 way communication and you can push information back to the users. There are several third-party solutions that you can find in the Internet that allows you to use websockets. Some of them are

  • Pusher
  • PubNub
  • Ably
  • Socket.io

Then there is Socketi, which is different from socket.io. It is simple, fast, and resilient open-source WebSockets server. "The server is built on top of uWebSockets.js - a C application ported to Node.js. uWebSockets.js is demonstrated to perform at levels 8.5x that of Fastify and at least 10x that of Socket.IO." (source: Socketi). 

The way these systems work is that when you send the message to the websocket server, the websocket server sends the message to the client system at a defined port. You can imagine the websocket as that delivery man who takes the flyers from you and sends it to all those people who have agreed to receive the flyers. PusherJs is pretty popular when we talk about websockets in web world. Socketi is compatible with PusherJs protocol so if you are planning to migrate your websocket implementation, it should be easy as.

Learn by Example

Let's look at a simple example here. The code below is a simple html and javascript code. It uses PusherJs api and defines the websocket server being present at localhost i.e. 127.0.0.1 and listening at port 6001. Once the message is received through 'my-event' in 'my-channel' it just displays in the frontend. I've implemented it using VueJs, but it should be similar for other javascript frameworks or pure javascript.

const PusherJS = window.Pusher;

let client = new PusherJS('a1234', {
    wsHost: '127.0.0.1',
    wsPort: 6001,
    forceTLS: false,
    encrypted: true,
    disableStats: true,
    enabledTransports: ['ws', 'wss'],
});

client.subscribe('my-channel').bind('my-event', (data) => {
    console.log(data.message)
    this.message = data.message;
    this.messages.unshift(data.message);
});

The above code just defines the client object and subscribes to particular event in a particular channel. Below is the full code. You can copy it and paste it in an html file and open it in a browser

<html>
  <head>
    <script src="https://js.pusher.com/7.0/pusher.min.js"></script>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">

    <script>

    window.onload = function(){
      new Vue({
        el: '#app',
        data: {
          message: 'Your message will appear here',
          messages: []
        },
        created() {
          const PusherJS = window.Pusher;

          let client = new PusherJS('a1234', {
              wsHost: '127.0.0.1',
              wsPort: 6001,
              forceTLS: false,
              encrypted: true,
              disableStats: true,
              enabledTransports: ['ws', 'wss'],
          });

          client.subscribe('my-channel').bind('my-event', (data) => {
              console.log(data.message)
              this.message = data.message;
              this.messages.unshift(data.message);
          });
        }
      });
    }
    </script>
  </head>
  <body>
    <div class="container" id="app">
      <h3>Current Message</h3>
      <div class="alert alert-success" role="alert">{{message}}</div>
      <div v-if="messages.length">
        <h3>Old Messages</h3>
        <div v-for="(m,i) in messages" class="alert alert-primary" role="alert">{{m}}</div>
      </div>
    </div>
  </body>
</html>

Now run the below code in your terminal to start the socketi server. It has configuration to match with the settings defined in the frontend. Eg. app_id and app_key

docker run -p 6001:6001 -p 9601:9601 -e SOKETI_DEBUG=1 -e SOKETI_DEFAULT_APP_ID=a1234 -e SOKETI_DEFAULT_APP_KEY=a1234 -e SOKETI_DEFAULT_APP_SECRET=a1234 quay.io/soketi/soketi:1.4-16-debian

At this point you've got a websocket server and a client that listens to the events. Now you need to send the message to the websocket server. Now I'm using PusherJs server API to send the message to the server. This implementation is in PHP but if you are using other backend language, you would have to refer PusherJs documentation. PusherJs has examples of integration with multiple languages. The below code has same configuration as the one used by client and websocket server. I've saved the below file in test.php

<?php
// First, run 'composer require pusher/pusher-php-server'
require __DIR__ . '/vendor/autoload.php';

$pusher = new Pusher\Pusher(
  "a1234",
  "a1234",
  "a1234",
  [
    'host' => '127.0.0.1',
    'port' => 6001,
    'scheme' => 'http',
    'encrypted' => true,
  ]
);
//This will send the message to my-channel via my-event event
$pusher->trigger('my-channel', 'my-event', ['message' => 'This is insane, Time:' . date('Y-m-d H:i:s') ]);

Now you can open the previously created html file in one window and run the php script in terminal. 

php test.php

Run this command in terminal in the directory where your test.php is to have some fun.

x=1; while  [ $x -le 5 ]; do php test.php && echo "Run test $x times" $(( x++ )); sleep 2; done
soketiweb socketvuejslaravelphppusher jsjavascriptsimpleexamplebeginnerprogrammersocket.io

Latest Post

Information retrieval – Searching of text using Elasticsearch

Information retrieval is the process of obtaining relevant information resources from the collection of resources relevant to information need.

Learn more
© 2023 www.lamadly.com