NodeJS+Redis实现Web实时通讯聊天模块
2014-01-26 00:45
816 查看
需要安装NodeJS,以及相关包如redis,socket.io等。
服务端node js代码:
客户端代码:
服务端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>
相关文章推荐
- NodeJS+Socket.io+ExpressJS实现web聊天应用
- dwr实现javaweb实时聊天通讯网页版常见问题及解决方案
- node.js系列(模块):request模块实现与php的通讯
- 我的小工具-远程读卡器web客户端(nodejs+websocket实现实时指令交互)
- NodeJs WS 模块 实现 WebSocket 聊天
- 安卓SocketIO+Node.js实现好友与好友间的实时聊天
- websocket+node.js实现实时聊天系统问题咨询
- 基于Node.js的web聊天系统 - 真正意义上的web实时聊天系统
- nodejs+socketio+redis实现前端消息实时推送
- Spring+WebSocket+SockJS实现实时聊天
- 游戏任务成就体系的实现(五):通讯模块(MsgUtil)基于NodeJS+TCP的机制的实现
- 使用node.js实现微信小程序实时聊天功能
- Node.js之网络通讯模块实现浅析
- Nodejs + azure +webrtc 实现android 和web视频聊天步骤
- 使用Node.js的socket.io模块开发实时web程序
- Python+React+Websocket+Redis实现的实时多人聊天
- nodejs+express+websocket+redis实现消息订阅系统
- nodejs+socketio+redis实现前端消息实时推送
- 使用Node.js的socket.io模块开发实时web程序
- rtags——node.js+redis实现的标签管理模块