Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private Chat Messaging using Node.js, Socket.io, Redis in PHP

I am working for a real time private messaging system into my php application. My codes are working for all users together. But I need private messaging system as one-to-one message.

After setup node and redis I can get the message data what I need : here is the code ::

Front-end :: 1. I use a form for - username , message and send button

and Notification JS:

$( document ).ready(function() {

    var socket = io.connect('http://192.168.2.111:8890');

    socket.on('notification', function (data) {
        var message = JSON.parse(data);
        $( "#notifications" ).prepend("<p> <strong> " + message.user_name + "</strong>: " + message.message + "</p>" );

    });

});

Server Side js:

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

server.listen(8890);

var users = {};
var sockets = {};

io.on('connection', function (socket) {

    console.log(" New User Connected ");
    // instance of Redis Client
   var redisClient = redis.createClient();
   redisClient.subscribe('notification');

   socket.on('set nickname', function (name) {
       socket.set('nickname', name, function () {
           socket.emit('ready');
       });
   });

  socket.on('msg', function () {
    socket.get('nickname', function (err, name) {
        console.log('Chat message by ', name);
    });
  });


   redisClient.on("message", function(channel, message)
   {
     // to view into terminal for monitoring
     console.log("Message from: " + message + ". In channel: " + channel + ". Socket ID "+ socket.id );

     //send to socket
     socket.emit(channel, message);
   });

   redisClient.on('update_chatter_count', function(data)
   {
      socket.emit('count_chatters', data);
   });

   //close redis
   socket.on('disconnect', function()
   {
      redisClient.quit();
   });

 });

HTML::

<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<form .....>
<input ....... >
</form>
<div id="notifications" ></div>

Over-all output:

John : Hello
Kate : Hi
Others: .....

Above codes are working nicely in my php application. Now I want to set-up private or one-to-one messaging system.

The way I need to add username or email or unique socketID for user. I do not have any more ideas for private messaging. I tried to figure on online but failed.

**How do I setup private message into my php application ? **

like image 948
Selim Reza Avatar asked May 16 '16 05:05

Selim Reza


3 Answers

Basic initialization of variables:-

First, make a MAP of mapOfSocketIdToSocket and then send the userid of the specific user to whom you want to sent the message from the front-end. In the server, find the socket obeject mapped with the userid and emit your message in that socket. Here is a sample of the idea (not the full code)

  var io = socketio.listen(server);
  var connectedCount = 0;
  var clients = [];
  var socketList = [];
  var socketInfo = {};
  var mapOfSocketIdToSocket={};

  socket.on('connectionInitiation', function (user) {
      io.sockets.sockets['socketID'] = socket.id;
      socketInfo = {};
      socketInfo['userId']=user.userId;
      socketInfo['connectTime'] = new Date();
      socketInfo['socketId'] = socket.id;
      socketList.push(socketInfo);

      socket.nickname = user.name;
      socket.userId= user.userId;

      loggjs.debug("<"+ user.name + "> is just connected!!");

      clients.push(user.userId);
      mapOfSocketIdToSocket[socket.id]=socket;
  }
  socket.on('messageFromClient', function (cMessageObj, callback) {
     for(var i=0; i<socketList.length;i++){
       if(socketList[i]['userId']==cMessageObj['messageToUserID']){ // if user is online
        mapOfSocketIdToSocket[socketList[i]['socketId']].emit('clientToClientMessage', {sMessageObj: cMessageObj});
        loggjs.debug(cMessageObj);
      }
    }
  })

Either you may want to go for private one-to-many chat room or you can go for one-to-one channel communication (if there are only two members communicating) http://williammora.com/nodejs-tutorial-building-chatroom-with/

like image 121
sharif2008 Avatar answered Nov 17 '22 15:11

sharif2008


I would suggest you to use socketIO namespaces, it allow you to send / emit event from / to specific communication "channels".

Here is the link to socketIO documentation regarding rooms & namespaces

http://socket.io/docs/rooms-and-namespaces/

Cheers

like image 35
erwan Avatar answered Nov 17 '22 14:11

erwan


One solution could be sending messages to person with the particular socket id. As you are already using redis you can store the user's detail and socket id in redis when user joins and then to send messages to user by getting the socket id from the redis whenever you want to send him a message. Call events like

socket.emit('send private') from front end

and on backend handle the

socket.on('send private'){ // do redis stuff inside this }

like image 1
Avinash Avatar answered Nov 17 '22 14:11

Avinash