发送私有消息或向socket.io中的特定用户发送消息的问题

时间:2015-11-24 10:44:55

标签: php node.js redis socket.io chat

我正在使用Node.js,Redis,PHP,Socket.io开发聊天应用程序。我会使用广播向多个用户发送消息,但我无法向特定用户发送消息。任何人都可以为我提供如何实现一对一聊天或发送私人消息的解决方案吗?

以下是我的Server.js和client.js的代码库。

  

Server.js

    /*
 * -------------------
 * 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<command>)
 * Sorted set name : channels
 */
var channel_Count = 0;
var channel_name = "channel";
var user_channel = 0
/*
 * Lists of all users (sorted set using Z<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<command>)
 * 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 <user>
  var countMember = smembers <user>;
  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 && 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 < 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 && uName && 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 && data.uid !== undefined && 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 >= 12){ mid='pm';}
    else{ mid='am';}
    var time = (dt.getHours() < 10?'0':'')+dt.getHours()+ ":" + (dt.getMinutes() < 10?'0':'')+dt.getMinutes() + ":" + (dt.getSeconds() < 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 () {
  });
});
  

Client.js

<script src="<?php echo Yii::app()->request->baseUrl . "/js/socket.io.js"; ?>"></script>
<script language="javascript">
$(function () {
    var socket = io.connect("http://localhost:3000/");
    // select2
    var reciver_id;
    var sender_id = "<?php echo Yii::app()->session['user_id'];?>";
    var sender_name = "<?php echo Yii::app()->session['username'];?>";
    $("#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\
            <div class=\"chat-row\">\n\
            <div class=\"name-me\">" + data[i].from + "</div>\n\
            <div class=\"chat-text\">" + data[i].msg + "</div>\n\
            <div class=\"chat-time\">" +"Reciver :"+data[i].reciver+ "</div>\n\
            </div>");
        }
    });
    socket.on('disconnect', function(){});
});    
</script>

1 个答案:

答案 0 :(得分:1)

发送&#34;私人&#34;消息你必须知道服务器端的其他用户socket.id。

然后只需发送

socket.broadcast.to( other_user_socket_id ).emit( "hello" );