Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the thing we need to configure to implement live notification module (using redis and socket.io) in https server?

I have done a successfully live notification module in my local machine. I need to implement this module in live server. Live server is https. I don't know what are the things we need to change for https. Please check my code and help to integrate this on https server. Thanks.

ssl files

SSLCertificateFile /etc/letsencrypt/live/dev.test.de/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/dev.test.de/privkey.pem

socket.js

var app   = require('express')();
var http  = require('http').Server(app);
var io    = require('socket.io')(http);
var redis = require('redis');

io.on('connection', function(socket){
    console.log('a user connected');

    var redisClient = redis.createClient();

    /* Realtime message subscribe */
    redisClient.subscribe('message');
    redisClient.on('message', function(channel, message){
        /*console.log('new message in queue', channel, message);*/
        socket.emit(channel, message);
    });

    /* Realtime inquiry subscribe */
    redisClient.subscribe('inquiryCount');
    redisClient.on('inquiryCount', function(channel, message){
        /*console.log('new inquiry in queue', channel, message);*/
        socket.emit(channel, message);
    });

    socket.on('disconnect', function(){
        redisClient.quit();
        console.log('user disconnected');
    });
});


http.listen(3000, function(){
    console.log('listening on *:3000');
});

app.blade.php

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
    <script>
        var socket = io('{{env('APP_URL')}}:3000');
        /* Realtime message notification */
        socket.on('message', function(data){
           if(data){
               /* var res = $.parseJSON(data);*/
               $('.messages-menu').empty();
               $('.messages-menu').html(data);
           }
        });
        /* Realtime inquiry notification */
        socket.on('inquiryCount', function(data){
            if(data){
                $('.tasks-menu').empty();
                $('.tasks-menu').html(data);
            }
        });
    </script>

DashboardController.php

public function privateMessageAPICount($id)
{
      $message = 'taking count of data';
      if(count($message) > 0){
           $redis = Redis::connection();
                $redis->publish('message', $message);
                return response()->json(['status' => 'success'], 200);
        }
        else {
            return response()->json(['status' => 'No Result'], 404);
        }
 }

public function inquiryAPIUnreadCount($id)
{
   $inquiryCount .= 'taking count of data';
   if(count($inquiryCount ) > 0){
         $redis = Redis::connection();
          $redis->publish('inquiryCount', $inquiryCount);
          return response()->json(['status' => 'success'], 200);
        }
        else {
            return response()->json(['status' => 'No Result'], 404);
        }              
 }
like image 352
Sarath TS Avatar asked Oct 20 '17 10:10

Sarath TS


3 Answers

When your apache server is already configured using https, you just have to implement https to your ws-server. Since this is a node http server, this modified code should work (based on this post):

var app   = require('express')();
var fs = require('fs');
var privateKey  = fs.readFileSync('/etc/letsencrypt/live/dev.test.de/privkey.pem', 'utf8');
var certificate = fs.readFileSync('/etc/letsencrypt/live/dev.test.de/fullchain.pem', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var https  = require('https').createServer(credentials, app);
var io    = require('socket.io')(https);
var redis = require('redis');


io.on('connection', function(socket){
    console.log('a user connected');

    var redisClient = redis.createClient();

    /* Realtime message subscribe */
    redisClient.subscribe('message');
    redisClient.on('message', function(channel, message){
        /*console.log('new message in queue', channel, message);*/
        socket.emit(channel, message);
    });

    /* Realtime inquiry subscribe */
    redisClient.subscribe('inquiryCount');
    redisClient.on('inquiryCount', function(channel, message){
        /*console.log('new inquiry in queue', channel, message);*/
        socket.emit(channel, message);
    });

    socket.on('disconnect', function(){
        redisClient.quit();
        console.log('user disconnected');
    });
});


https.listen(3000, function(){
    console.log('listening on *:3000');
});

Your APP_URL has to start with https://.

I would recommend to use laravel-echo-server to handle ws-connections, it's much simpler

like image 187
cre8 Avatar answered Oct 23 '22 14:10

cre8


I cant write it as a command @sam sam.

only need to do is

    http{
    server {
            listen       443 ssl;
            server_name  localhost;
            keepalive_timeout  5;
            proxy_connect_timeout 7d;
            proxy_send_timeout 7d;
            proxy_read_timeout 7d;

            # Self-signed certificate.
            ssl_certificate ../ssl/server.crt;
            ssl_certificate_key ../ssl/server.key;
            ssl_protocols         SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;

            location / {
                proxy_pass http://apache_nodes/;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_redirect off;

                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
    }
       upstream apache_nodes {
        server 192.168.1.155;
    }

}

This will quarantee you to handle 443 and send client to 80 via proxy pass.

For more information please look at nginx ssl proxy server. With using the same proxy server usage , you can also handle your socket.io request over 443

for this

 upstream socket_nodes_1 {
        server 192.168.1.155:1337;
    }
location /sockets {
            proxy_pass http://socket_nodes_1/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_redirect off;

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

Regards,

like image 24
Emre Karataşoğlu Avatar answered Oct 23 '22 15:10

Emre Karataşoğlu


This is my working socket_https.js :

const fs = require('fs');

const options = {
    key: fs.readFileSync('/etc/letsencrypt/live/dev.test.de/privkey.pem'),
    cert: fs.readFileSync('/etc/letsencrypt/live/dev.test.de/fullchain.pem'),
    NPNProtocols: ['http/2.0', 'spdy', 'http/1.1', 'http/1.0']
};

var server = require('https').Server(options);

var io = require('socket.io')(server);


var Redis = require('ioredis');
var redis = new Redis();

redis.subscribe('message-channel');

redis.on('message', function (channel, message) {
    console.log('Message Receive');
    console.log(message);
    message = JSON.parse(message);

    io.emit(channel + ':' + message.event, message.data);
});

server.listen(4000);

Then When I want to publish to redis :

$data = [
      'event' => 'someEvent',
      'data'  => [
                      'id' => $id,
                      [...]
                  ]
];

Redis::publish('my-channel', json_encode($data));
like image 3
Mathieu Ferre Avatar answered Oct 23 '22 16:10

Mathieu Ferre