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

4

9

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 ? **

Degenerate answered 16/5, 2016 at 5:57 Comment(0)
T
6

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/

Thundercloud answered 16/5, 2016 at 15:53 Comment(8)
sample app : justchatnow.herokuapp.com and source code github.com/codebazz/justchatnowThundercloud
:: its not working in private messaging. I think I am missing something. Would you please guide me little more as server side and client side using redis client ?Degenerate
@Md. Sariful islam It seems open chatting box where all user can send and receive message in one location. But it seems it would be one to one messaging system.Ulterior
It is not a direct solution. I just tried to help him with some idea. Someone may help himThundercloud
@Md. Sariful islam :: I can do for public chat but I need to set private as one-to one messaging system. Would you please guide me ?Degenerate
First make a map user_id=>socket_id and another socket_id=>user_id in the server then from client side pass from_user_id, to_user_id and message to server. In the server iterate those map to get the from_socket_id, to_socket_id then emit the message in the specific to_socket_id. Thanks all.Thundercloud
@Md. Sariful islam :: I didn't you . As I did for user_id and partner_id but can not socket for specific user ... How may I get socket.id for sender or receiver ?Degenerate
yeah there is always a Socket_id when a user is connected to server. Save those socket id and user id in a map in the server side. When message passing the pass client_id(user_id) from the browser and in the server side get relevant socket_id from that map and pass the message in that socket.Thundercloud
T
3

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

Tailgate answered 25/5, 2016 at 10:36 Comment(0)
P
1

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 }

Primordium answered 29/5, 2016 at 1:8 Comment(0)
B
0

Use Pusher. It offers channel usage to make private chats possible without any additional code

Bimetallic answered 27/5, 2016 at 8:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.