title: Issue with send private message or send message to specific user in socket.io
body: <p>I am developing chat application using Node.js, Redis, PHP, Socket.io. I would use broadcast to send message to multiple user but I failed to send message to specific user. Can anyone provide me solution that how to implement one to one chat or send private message?</p>
  
  <p>Following is my code base of Server.js and client.js.</p>
  
  <blockquote>
    <p>Server.js</p>
  </blockquote>
  
  <pre><code>    /*
   * -------------------
   * Express
   *
   * -------------------
   */
  var app = require('express')(),
          http = require("http"),
          url = require('url'),
          cookieParser = require('cookie-parser'), 
          // the session is stored in a cookie, so we use this to parse it
          session = require('nodePhpSessions').SessionHandler,
          sessionHandler = new session(),
          morgan = require("morgan"),
          expressSession = require("express-session"),
          phpUnserialize = require("php-unserialize"),
          sessionStore = new expressSession.MemoryStore(),
          parseUrl = null, uId = null, uName = null, uEmail = null;
  // Transaction logger
  app.use(morgan("dev"));
  // must use cookieParser before expressxSession
  app.use(cookieParser());
  app.use(expressSession({
      name: "Whizchat",
      secret: '47760ae7-9660-4d4c-b15d-b9986edccbf3ss',
      store: sessionStore,
      saveUninitialized: true,
      resave: true,
      cookie: {
          path: "/",
          httpOnly: true,
          secure: true,
          maxAge: null,
      }
  }));
  app.use(function (req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "X-Requested-With");
      res.header("Access-Control-Allow-Headers", "Content-Type");
      res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
      next();
  });
  app.set('host', "localhost");
  app.set('port', "3000"); //process.env.PORT
  /*
   * -------------------
   * Socket Connections
   * -------------------
   */
  var server = http.createServer(function (req, res) {
      parseUrl = url.parse(req.url, true).query;
      if ("string" === typeof (parseUrl.dataJSON)) {
        var _objUser = JSON.parse(parseUrl.dataJSON);
        uId = (_objUser.user_id === undefined || _objUser.user_id === "" || _objUser.user_id === null) ? null : _objUser.user_id;
        uName = (_objUser.username === undefined || _objUser.username === "" || _objUser.username === null) ? null : _objUser.username;
        uEmail = (_objUser.user_email === undefined || _objUser.user_email === "" || _objUser.user_email === null) ? null : _objUser.user_email;
      }
      res.writeHead(200, {'Content-type': "text/plain"});
      res.end(sessionHandler.run(parseUrl));
  });
  var io = require('socket.io')(server);
  server.listen(app.get("port"), app.get("host"), function () {
      console.log("Server up and running...");
  });
  server.on('error', function (e) {
      console.log("Error occured :" + e);
  });
  /*
   * -------------------
   * Redis 
   * -------------------
   */
  var redis = require("redis");
  /*
   *  Sender
   */
  var publisher = redis.createClient();
  /*
   * Receiver
   */
  var subscriber = redis.createClient();
  /*
   * List of all channels (sorted set using Z&lt;command&gt;)
   * Sorted set name : channels
   */
  var channel_Count = 0;
  var channel_name = "channel";
  var user_channel = 0
  /*
   * Lists of all users (sorted set using Z&lt;command)
   * Sorted set name : onlineusers
   */
  var userlists = [], usersSocket = [];
  var uids = [], socketids = [];
  var get_old_communication_channel_name = "";
  /*
   * All Users related channels set ( unordered/unsorted set using s&lt;command&gt;)
   * Unsorted set name : userschannel
   */
  var usersChannels;
  var msgChannel = "messageChannelSet";
  var messageTable = "messageTable";
  /*
   * Message set (sorted set)
   */
  var message_Id = 1;
  //global array 
  var arr_msg_id = [];
  var arr_sender_reciver_msg = [];
  /*
   * User set
   */
  var channelSet;
  var countMember, countChannel;
  /*
   * Identified that user_reference_id based set (unordered) is generated or not
   */
  /*
  foreach userSet on &lt;user&gt;
    var countMember = smembers &lt;user&gt;;
    if(countMember is empty set or nil){
        isNewChannelGenerate = true;
    }
  endforeach
  */
  /*
   * -------------------
   * Mysql
   * -------------------
   */
  /*var mysql = require("mysql");
   var connection = mysql.createConnection({
   host: "localhost",
   user: "root",
   password: "password",
   database: "whiz"
   });
   connection.connect();*/
  /*
   * -------------------
   * functions
   * -------------------
   */
  function subscribeMessage(_subscriber) {
    subscriber.subscribe(_subscriber);
    subscriber.on("message", function (channel, message) {
      console.log("redis connection message:" + message);
    });
  }
  function setMessageData(msg){
    console.log("message call");  
    arr_sender_reciver_msg.push(JSON.stringify(msg));
  }
  function pushToRedis(subscriber, data) {
    console.log("push to channel"+JSON.stringify(data));
    console.log(" call first push ..."+data.uId+"==="+data.reciver);
    var msg = data.msg;
    var channel_name;
    if(data.uId &amp;&amp; data.reciver){
        subscriber.SINTER("user_"+data.uId, "user_"+data.reciver,  function(err, replies) {
        console.log("get_old_communication_channel_name  :"+get_old_communication_channel_name+"=="+replies);    
        if(get_old_communication_channel_name != replies) {
              arr_msg_id.splice(0,arr_msg_id.length);
              arr_sender_reciver_msg.splice(0,arr_sender_reciver_msg.length); 
        }
        get_old_communication_channel_name = replies;
        //one to one communication in message new create  channels replies == 0 then
        console.log("replies SCARD  :"+replies.length);
        if(replies.length == 0){
            var channel_Count_no;
            subscriber.SCARD(msgChannel, function(err, channel_Count) {
            console.log("channel_Count  :"+channel_Count);
            if(channel_Count == 0){
              channel_name = "channel1";
              subscriber.SADD("user_"+data.uId, "channel1");    
              subscriber.SADD("user_"+data.reciver, "channel1");
              subscriber.SADD("channelSet", "channel1");  
            }else{
              channel_Count_no = channel_Count + 1;
              channel_name = "channel"+channel_Count_no;
              subscriber.SADD("user_"+data.uId, "channel"+channel_Count_no);    
              subscriber.SADD("user_"+data.reciver, "channel"+channel_Count_no);
              subscriber.SADD("channelSet", "channel"+channel_Count_no); 
             // subscriber.SADD(msgChannel, "message_channel"+channel_Count_no); 
            }
          });
        }
        console.log(" call first push1 ...");    
        //one to one communication in message new create  channels replies == 1 then
        if(replies.length == 1){ 
          get_old_communication_channel_name = replies; 
          channel_name = replies;     
          console.log("ch_name :"+replies);
          console.log("data.msg  :"+msg);
          console.log("msgChannel  :"+msgChannel);
          console.log("arr_msg_id.length  :"+arr_msg_id.length);
          if(arr_msg_id.length &lt; 1 ){
            console.log("arr_msg_id.length After  :"+arr_msg_id.length);
            subscriber.HGETALL("message_"+channel_name, function(err, replies1) {
              /*
               * HGETALL  redis command to get all redord and for lop to javascript insert in this arr_msg_id array.
               * After for loop to get all record in messageTable.
               */
              for (i in replies1) {
                arr_msg_id.push(JSON.parse(replies1[i]));
              }
              console.log(arr_msg_id.length);
              for (i in arr_msg_id) {
                var _index = arr_msg_id[i];
                subscriber.HGET(messageTable, _index, function(err, replies2) {
                   arr_sender_reciver_msg.push(JSON.parse(replies2));
                });
              }
            });
          }
        }
        subscriber.HLEN(messageTable, function(err, replies1) {
          subscriber.SADD(msgChannel, "message_"+channel_name);
          message_Id = replies1 + 1;
          subscriber.HSET(messageTable, message_Id, JSON.stringify(data), function(err, reply) {
            if (err) throw err;
          });
          /*
          * message_channel1,2,3....
          * that match message_channel in insert ID and massage_text.
          */
          subscriber.HSET("message_"+channel_name, "msg_"+message_Id, message_Id);
        });
      });
    }
  }
  function getCurrentTime() {
    return Math.floor(new Date().valueOf() / 1000);
  }
  function accessSecureSessionInfo() {  
    if ("string" === typeof (parseUrl.dataJSON)) {
      console.log("step in 1");
      var _objUser = JSON.parse(parseUrl.dataJSON);    
      uId = (_objUser.user_id === undefined || _objUser.user_id === "" || _objUser.user_id === null) ? null : _objUser.user_id;
      uName = (_objUser.username === undefined || _objUser.username === "" || _objUser.username === null) ? null : _objUser.username;
      uEmail = (_objUser.user_email === undefined || _objUser.user_email === "" || _objUser.user_email === null) ? null : _objUser.user_email;
    }
  }
  /* 
   * -------------------
   * Redis Subscriber
   * -------------------
   */
  if (uId &amp;&amp; uName &amp;&amp; uEmail) {
      subscriber.subscribe("whizbitechannel");
    subscribeMessage("whizbitechannel");
  }
  var basket = {};
  var index =0;
  io.sockets.on('connection', function (socket) {
    var _subscriber = redis.createClient();
    socket.on('connection', function (cma) {
      console.log('Server running on *:' + app.get('port'));      
    });
    console.log("index:"+index++);
    socket.on("join",function(data){
      console.log("before start:"+userlists.length);
      console.log("datauid:"+data.uid);
      if(data.uid !== null &amp;&amp; data.uid !== undefined &amp;&amp; data.uid !== "") {          
        var _socketid = socket.id;
        var _uid = data.uid;
        var _findIndex = uids.indexOf(_uid)
        if(_findIndex === -1){
          uids.push(_uid);
          socketids.push(_socketid);        
        }else if(_findIndex !== -1){
          socketids[_findIndex] = _socketid;
        }
        io.sockets.sockets[_uid] = _socketid;
      }
    });
    socket.on("chat1", function (data) {
        var _data = {
        uId : data.sender_id,
        from: data.sender_name,
        msg: data.msg,
        reciver : data.reciver
      };
      pushToRedis(_subscriber, _data); 
    });
    socket.on("chat", function (data) {
      var dt = new Date();
      var hours = dt.getHours();
      var mid;
      if(hours &gt;= 12){ mid='pm';}
      else{ mid='am';}
      var time = (dt.getHours() &lt; 10?'0':'')+dt.getHours()+ ":" + (dt.getMinutes() &lt; 10?'0':'')+dt.getMinutes() + ":" + (dt.getSeconds() &lt; 10?'0':'')+dt.getSeconds()+" "+mid;
      var _data = {
        uId : data.sender_id,
        from: data.sender_name,
        msg: data.msg,
        reciver : data.reciver,
        //date: time
        //date: getCurrentTime()
      };
      arr_sender_reciver_msg.push({uId : data.sender_id,from : data.sender_name,msg : data.msg, reciver : data.reciver});
      var _sender_id = data.sender_id;    
      var _uIndex = uids.indexOf(data.reciver.toString());
      if(_uIndex !== -1){
        var _socketId = socketids[_uIndex];
        io.sockets.socket[_socketId].send("publishMessage", arr_sender_reciver_msg); 
      }
    });
    socket.on('disconnect', function () {
    });
  });
  </code></pre>
  
  <blockquote>
    <p>Client.js</p>
  </blockquote>
  
  <pre><code>&lt;script src="&lt;?php echo Yii::app()-&gt;request-&gt;baseUrl . "/js/socket.io.js"; ?&gt;"&gt;&lt;/script&gt;
  &lt;script language="javascript"&gt;
  $(function () {
      var socket = io.connect("http://localhost:3000/");
      // select2
      var reciver_id;
      var sender_id = "&lt;?php echo Yii::app()-&gt;session['user_id'];?&gt;";
      var sender_name = "&lt;?php echo Yii::app()-&gt;session['username'];?&gt;";
      $("#e1").select2();
      $("#e1").change(function(){
          $('.chatlog').html('');
          reciver_id=$(this).val();
          return false;
      });
      /*
       * -------------------
       * Methods
       * -------------------
       */
      $.fn.clearAndFocus = function (){
          $("#txtMessage").val("").focus();
      };
      $.fn.sendMessageToServer = function(){
          socket.emit("chat1", {sender_id:sender_id, sender_name:sender_name, reciver:reciver_id, msg: $("#txtMessage").val()});            
          $.fn.clearAndFocus();
      };
      $.fn.clearAndFocus();
      /*
       * -------------------
       * Events
       * -------------------
       */
      $("#btnSend").on("click", function () {
          $.fn.sendMessageToServer();
      });
      $("#txtMessage").on("keyup", function (e) {
          if (e.keyCode === 13) {
              $.fn.sendMessageToServer();
              $.fn.clearAndFocus();
          }
      });
      /*
       * -------------------
       * Socket Events
       * -------------------
       */
      socket.on('connect', function () {
          console.log("whiz client is connected");
          socket.emit("join",{uid:sender_id});
      });
      socket.on("publishMessage", function (data) {
          $('.chatlog').html('');
          for(i in data)
          {
              $(".chatlog").append("\n\
              &lt;div class=\"chat-row\"&gt;\n\
              &lt;div class=\"name-me\"&gt;" + data[i].from + "&lt;/div&gt;\n\
              &lt;div class=\"chat-text\"&gt;" + data[i].msg + "&lt;/div&gt;\n\
              &lt;div class=\"chat-time\"&gt;" +"Reciver :"+data[i].reciver+ "&lt;/div&gt;\n\
              &lt;/div&gt;");
          }
      });
      socket.on('disconnect', function(){});
  });    
  &lt;/script&gt;
  </code></pre>