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

S.Reza
  • 345
  • 4
  • 18

4 Answers4

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/

desertSniper87
  • 795
  • 2
  • 13
  • 25
sharif2008
  • 2,716
  • 3
  • 20
  • 34
  • sample app : http://justchatnow.herokuapp.com/ and source code https://github.com/codebazz/justchatnow – sharif2008 May 16 '16 at 16:00
  • :: 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 ? – S.Reza May 17 '16 at 07:29
  • @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. – naf4me May 17 '16 at 07:29
  • It is not a direct solution. I just tried to help him with some idea. Someone may help him – sharif2008 May 17 '16 at 09:53
  • @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 ? – S.Reza May 18 '16 at 03:51
  • 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. – sharif2008 May 18 '16 at 17:09
  • @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 ? – S.Reza May 19 '16 at 07:50
  • 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. – sharif2008 May 19 '16 at 11:37
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

erwan
  • 887
  • 8
  • 17
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 }

Avinash
  • 419
  • 2
  • 11
0

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

Srirag Nair
  • 166
  • 1
  • 8