您的位置:首页 > 数据库 > Redis

NodeJS+Redis实现Web实时通讯聊天模块

2014-01-26 00:45 816 查看
需要安装NodeJS,以及相关包如redis,socket.io等。

服务端node js代码:

var redis_host = '127.0.0.1', redis_port = 6379;
var redis = require("redis"), client = redis.createClient(redis_port, redis_host);

var io = require('socket.io').listen(4000);
io.set('log level', 1);
io.set('transports', ['websocket' ,'flashsocket' ,'htmlfile' ,'xhr-polling' ,'jsonp-polling']);

var online_user_chat_key = "chat:";
var online_user_list_key = "user:list";

var sockets = [];
var user_info_hash = {};
var socket_user_hash = {};

io.sockets.on('connection', function (socket) {

socket.on('add-user', function(data) {
var user = JSON.parse(data).user;
var id_user = user.id;
user_info_hash[id_user] = user;
socket_user_hash[socket.id] = id_user;
client.sadd(online_user_list_key, id_user, function(err, res){
update_user_list(id_user, socket);
});
});

socket.on('send-message', function(data){
var msg = JSON.parse(data);
var id_target = msg.id_target;
var id_user = msg.id_user;
var message = msg.message;
var date_string = msg.date;
var id_chat = [id_user, id_target].sort().join("_");
var json = JSON.stringify({ 'id_user': id_user, 'id_target': id_target,  'message': message, 'date': date_string });
client.lpush(online_user_chat_key + id_chat, json, function(err, res){
if (undefined != sockets[id_chat]) {
for (var id_user in sockets[id_chat]){
for (var socket_id in sockets[id_chat][id_user]) {
sockets[id_chat][id_user][socket_id].emit('receive-message', json);
}
}
}
});
});

socket.on("disconnect", function() {
var user_id = socket_user_hash[socket.id];
if(undefined != user_id) {
client.srem(online_user_list_key, user_id, function(){
update_user_list(user_id, socket);
});
for(var id_chat in sockets) {
for(var id_user in sockets[id_chat]) {
if(id_user == user_id) {
delete sockets[id_chat][id_user];
}
}
}
}
});

socket.on("add-socket", function(data) {
var msg = JSON.parse(data);
var id_target = msg.id_target;
var id_user = msg.id_user;
store_socket(id_user, id_target, socket);
});
});

function update_user_list(id_user, socket) {
client.smembers(online_user_list_key, function(error, users) {
if(users.length > 0) {
var user_info = {};
for(var i in users) {
var user_id = users[i];
if(undefined != user_info_hash[user_id]) {
user_info[user_id] = user_info_hash[user_id];
}
}
show_online_users(user_info, id_user, socket);
}
});
}

function show_online_users(user_info, id_user, socket) {
var reply = JSON.stringify({ id_user: id_user, user_info: user_info });
io.sockets.emit('show-online', reply);
for(var id_target in user_info) {
store_socket(id_user, id_target, socket);
}
}

function store_socket(id_user, id_target, socket) {
if(id_user != id_target) {
var id_chat = [id_user, id_target].sort().join("_");
if (undefined == sockets[id_chat]) {
sockets[id_chat] = {};
}
if (undefined == sockets[id_chat][id_user]) {
sockets[id_chat][id_user] = {}
}
sockets[id_chat][id_user][socket.id] = socket;
}
}


客户端代码:

<script type="text/javascript" src="http://<?php echo $hostname; ?>:4000/socket.io/socket.io.js"></script>
<script type="text/javascript">

$(document).ready(function(){
$('.chat_icon_here img').each(function(){
$(this).attr('title', $(this).attr('alt'));
})
});

var info;
var month = ['Jan', 'Feb', 'Mar', 'Feb', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var new_msg_sound;
soundManager.setup({
url: '/sounds/swf/',
flashVersion: 9,
onready: function() {
// Ready to use; soundManager.createSound() etc. can now be called.
new_msg_sound = soundManager.createSound({
id: 'sound_new_msg',
url: '/sounds/msg.mp3'
});
}
});

var chat_logs = {};
var id_user = '<?php echo $userId; ?>';
var socket = io.connect('http://<?php echo $hostname; ?>:4000');
socket.emit('add-user', $.toJSON({ user: <?php echo json_encode($login_user); ?> }));

socket.on('show-online', function (msg) {
var message = $.evalJSON(msg);
info = message.user_info;
$("#user_list").empty();
var user_account = 0;
for(var user in info) {
try {
var username = (info[user].first_name)? (info[user].first_name+ " "+ info[user].last_name): info[user].username;
var avator = (info[user].avator)? info[user].avator : "/images/chat/chat_9.png";
if(user != id_user) {
//var image = "<li rel='" + user + "'><a href='javascript:show_chat(" +user+ ");' title='" +username+ "' class='showChat' user='" +user+ "'><image src='" +avator+ "' alt='" +username+ "' width='28'></a></li>";
var image ="<li rel='" + user + "'><span class='chat_photo'><a href='javascript:show_chat(" +user+ ");' class='showChat' title='Click to Chat with " +username+ "' user='"+ user+ "'><image src='" +avator+ "' alt='" +username+ "' width='28' height='28'></a></span><strong>" +username+ "</strong><span class='cl'></span></li>";
$("#user_list").append(image);
user_account++;
}
}
catch(e){}
}
$("#chat_amount").html(user_account);
var id_target = message.id_user;
socket.emit('add-socket', $.toJSON({ id_user: id_user, id_target: id_target }));
});

$('#message_box').keydown(function(event) {
if (event.keyCode == 13) {
var message = $('#message_box').val().trim();
if(!message) {
return false;
}
var id_target = $("#target").attr("rel");
var date = new Date();
var year = date.getFullYear()
var mon = date.getMonth()
var day = date.getDate()
var date_string = month[mon] + " "+ day + ", " + year;
socket.emit('send-message', $.toJSON({ id_target: id_target, id_user: id_user, message: message, date: date_string }));
if (chat_logs[id_target] == undefined) {
chat_logs[id_target] = {};
}
if (chat_logs[id_target][date_string] == undefined) {
chat_logs[id_target][date_string] = [];
}
chat_logs[id_target][date_string].push(id_user+"@_@"+ message);
$('#message_box').val("");
return false;
}
});

socket.on('receive-message', function (msg) {
var message = $.evalJSON(msg);
//console.log(message);
var target = message.id_user;
var id_target = message.id_target;
var avator = info[target].avator;
if(avator == null) {
avator = "/images/chat/chat_9.png";
}
var date_string = message.date;
var msg_user = info[target].first_name + " " + info[target].last_name;
var msg_content = decode_emotion(message.message);
if (chat_logs[target] == undefined) {
chat_logs[target] = {};
}
if (chat_logs[target][date_string] == undefined) {
chat_logs[target][date_string] = [];
}
chat_logs[target][date_string].push(target+"@_@"+msg_content);

if( ($('#chat_window').css("display") == "block" && $("#target").attr("rel") ==  target) || ($('#chat_window').css("display") == "block" && $("#target").attr("rel") == id_target) ) {
$("#chat_content").append(date_string+ "<hr size='1' /><img width='28' height='28' src='"+ avator+ "' alt='"+ msg_user+ "' align='top' /> " + msg_content);
$("#chat_content").append("<br/>");
$("#user_list a.showChat[user="+ target+ "] img").css({"border": "0px solid red"});
$("#chat_content")[0].scrollTop = $("#chat_content")[0].scrollHeight;
}
else {
$("#user_list a.showChat[user="+ target+ "] img").css({"border": "2px solid red"});
if (undefined != new_msg_sound){
new_msg_sound.play();
}
}
});

function emotion(emo) {
if(emo) {
$("#message_box").val($("#message_box").val() + " [:"+ emo+ "] ");
$('#chat_icon_all').slideToggle();
$("#message_box").focus();
}
}

function decode_emotion(emo) {
var ret_val = emo.replace(/\[:(([^\]]+))\]/gi, "<img  align='absmiddle' width='35' height='35' src='/images/chat/$1.png' title='$1' alt='$1' />");
return ret_val;
}

function show_chat(id) {
var target = id;
var username = info[target].first_name + " " + info[target].last_name;
var avator = info[target].avator;
if(avator == null) {
avator = "/images/chat/chat_9.png";
}
if(target != id_user) {
$("#target").text(username).attr("rel", target);
var chat_content = "";
if (chat_logs[target] != undefined) {
//console.log(chat_logs);
for(date_string in chat_logs[target]) {
var list = chat_logs[target][date_string];
for(i=0; i<list.length; i++)  {
var tmp = list[i].split("@_@");
var message_field = tmp[1];
var avator = info[tmp[0]].avator;
chat_content += date_string+ "<hr size='1' /><img width='28' height='28' src='"+ avator+ "' alt='"+ username+ "' align='top' /> " + decode_emotion(message_field)+ "<br />";
}
}
}
$("#chat_content").html(chat_content);
$("#user_list a.showChat[user="+ target+ "] img").css({"border": "0px solid red"});
$('#chat_window').slideToggle(500, function(){
$("#chat_content")[0].scrollTop = $("#chat_content")[0].scrollHeight;
});
}
}

function logout_user() {
socket.emit('disconnect');
}
</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: