2015-11-24 2 views
-2

Я разрабатываю приложение для чата с использованием Node.js, Redis, PHP, Socket.io. Я бы использовал широковещательную рассылку для отправки сообщения нескольким пользователям, но я не смог отправить сообщение конкретному пользователю. Может ли кто-нибудь дать мне решение, как реализовать один-один чат или отправить личное сообщение?Проблема с отправкой личного сообщения или отправкой сообщения конкретному пользователю в 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

Чтобы отправить "частное" сообщение, вы должны знать другие socket.id пользователя на сервере боковая сторона.

Тогда просто отправить его с

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

Спасибо за ваш ответ. Но он работает очень хорошо, когда предполагаемый человек может общаться с тем же человеком, который отправляет сообщение, но как отправить предупреждение тем, кто находится в режиме онлайн в окне чата, но не общаться со мной. Можете ли вы найти решение? Возможно использование pub-sub, но все еще путают, как управлять предупреждением на вкладке другому человеку. –

Смежные вопросы