websocket以及nodejs联手打造的类qq群聊天室 教程 附 原代码
这次给大家分享的是我自己开发的多人聊天室,利用websocket 以及服务器端使用node.js 来让用户不需要刷新浏览器就可以获得实时更新。
如下面图所示的样子。开发出类QQ群聊天室的主界面,当然UI还是有点难看。。。
使用的技术要点罗列:nodejs 安装与使用 websocket 客户端以及nodejs 服务器端的 API接口调用 js,jq 的用法 包括设置cookie date函数使用,html5 本地存储方式 local storage 的使用方法 以及表情的选择与发送这几个方面。现在跟我一起来完成它吧。
第一步,先了解下 websocket 是什么,为什么在线聊天室 需要这样的方式来进行,而传统的http模式有什么弊端。可以参考下百度百科中的websocket定义http://baike.baidu.com/link?url=UdkmadppMSP7B0LpZU1VUhCXW0kKii1oRZ8o-Pn77IHs_3KyCp70FKethp3TBNpsSuSC6fZw3hMlV7_ZZ20BZ_。当然现在如日中天的node.js已经完全封装好了websocket API的所有内容 ,当然大家可以去http://www.open-open.com/lib/view/open1402479198587.html看看websocket 是怎么定义的,websocket协议与平常http 协议有什么不一样。现在把这块内容稍微消化下,我们就可以开始动手开始实现吧。
安装node.js 。大家还是可以去看这篇http://www.open-open.com/lib/view/open1402479198587.html ,
根据自己的操作系统,去Node.js官网下载安装即可。如果成功安装。在命令行输入node -v
和npm -v
应该能看到相应的版本号。
当出来以上信息时候,说明你的node.js已经安装成功了!
搭建自己的websocket 服务器。 接下来使用npm
命令安装express
和socket.io
安装成功后,会在该文件夹下生成了一个名为node_modules
的文件夹,里面分别是express
和socket.io相关的文件集
,再这里新建个服务器的代码 server.js
就可以开始编写服务端的代码了。
server.js 最开始的代码
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);app.get('/',function(req,res){res.send('<h1>Welcome Realtime Server</h1>');
});http.listen(3000,function(){console.log('listening on *:3000');
});
这时候 你就可以运行下代码 node server.js 来开启服务了
出现该截图内容 就说明websocket服务器已成功 运行了,你也可以打开浏览器 ,输入localhost:3000来看看3000端口上运行的websocket服务器是否启动
接下来,就可以开始着手前端的准备工作(包括界面图片样式等等的) 一开始 我是抱着学习的心态 使用了http://www.oschina.net/code/snippet_230665_21329这里面的UI设计,大家也可以使用。好,我们先要运行起来,完成用户登录完 就能在后台收到信息的功能
var my_websocket = io.connect('ws://localhost:3000');//js获取当前时间var NowDateTime = getNowFormatDate();console.log(my_websocket);my_websocket.on('connect',function(){my_websocket.emit("login",tourist);my_websocket.on('login_message',function(message){//刚进聊天室时候在聊天框显示某某进入聊天室console.log(message);//每次登陆先删除右边栏所有的用户$("#userck").siblings().remove();scrollWindow()var self_content = "<span class=\"content_nowtime\">["+NowDateTime+"]</span>";self_content += " <a class=\"content_tourist\">"+message.user_now+"</a>来到了聊天室:<br><br>";content_div.append(self_content); //在右侧观众栏添加刚登陆的游客var ParentTourist = $("#autors"); for (i in message.user_array){var SonTourist = "<a class=\"userck\">"+message.user_array[i]+"</a>";ParentTourist.append(SonTourist); }var touristCount = "所有人-共 "+message.user_count+" 人";$("#userck").text(touristCount);});
当然后台也要加上获取客户端发送消息的代码
var userArr = new Array();var userCount = 0;
io.on('connection',function(socket)
{ console.log('a user connected');socket.on('login',function(obj) {//判断是否是新用户登录 indexOf是js 判断数组是否包含一个元素的函数 大于0表示包含 -1表示不包含 if(userArr.indexOf(obj) == '-1'){userArr.push(obj); userCount ++; }var login_message = { user_array : userArr, user_count : userCount, user_now : obj} console.log(login_message); //将所有用户登录的信息发给所有用户io.sockets.emit('login_message',login_message);});
还有一点主意的 客户端发送消息通知给服务器端代码时 是用
my_websocket.emit("login",tourist);
然后服务器端接收到单个客户端推送的信息时 ,他需要推送给所有在线的用户 所以需要使用
<pre name="code" class="javascript">io.sockets.emit('login_message',login_message);
这时候 客户端收到 服务器端返回的login_message值的时候 我们就要进行开发这个方法了
my_websocket.on('message',function(msg){//在聊天框添加聊天的记录sendTime = msg.send_time;username = msg.username;tourist_message = replace_em(msg.content);console.log(msg);if(getcookie("tourist") == username){var self_content = "<div class=\"receiver\">";self_content += "<div><img src=\"arclist/online_chat_face.jpg\" style=\"width:50px;height:50px\"></div>";self_content += "<div><div class=\"right_triangle\"></div>";self_content += "<p class=\"receiver_name_r\">"+username+"</p>";self_content += "<span>"+tourist_message+"</span>";self_content += "</div></div><br>";self_content += "<div class=\"clear\"></div>";/*var self_content = "<span class=\"content_nowtime\">["+sendTime+"]</span>";self_content += " <a class=\"content_tourist\">"+username+"</a>说:";self_content += tourist_message+"<br>";*/}else
当然大家也可以先用注释中的简单哪代码先来实现该方法 没有注释那段是使用类QQ群聊天那样的气泡模式 ,getcookie这个方法是调用了cookie的值来判断是不是本人发送的消息 ,如果是的话气泡就会在右边 如果发送成功的话 ,大家可以在服务器端看到如下的代码反馈
这样就说明传输成功了 ,当然到界面上就会有如下显示
当然完成这一步的时候。你就已经成功了一大半了,接下来就是不断调试,尝试着用虚拟机跟你对话吧,就像开头的截图一样。。。
附上源码链接 https://github.com/taweisuode/online_chat 大家可以去下载,我也会不定期去更新完善里面的内容。
好了。当大家把所有登录。发送消息。退出时候的消息都能够实时发送,并且右侧状态栏也能够实时显示在线人数以及在线人姓名时。我们就要对其进行完善以及优化了
可以添加以下内容 1. 按enter键发送消息;2.将一些用户信息存储在local storage 中;然后根据失效时间 是否删除所有的local Storage数据 ,这样可以判断你的上次登录时间;
3.当聊天内容多余div的高度时,我们需要使用滚动轴,源代码有简单使聊天框都在滚动轴最下方的代码;4.可以使用表情来发送;5.可以使用类QQ群聊天的气泡对话模式;
当然这些都放在源码中 。大家也可以去https://github.com/taweisuode/online_chat 下载。
大概就说这么多了,这是小弟我第一次发表博客,不足之处希望大家能够批评指正。如有不懂的问题。可以随时请教。我的联系方式1064480036@qq.com
以下贴出我的客户端 以及服务器端的源码。
客户端的代码
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>socket</title>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="chat_server/node_modules/socket.io-client/socket.io.js"></script>
<script type="text/javascript" src="jquery.qqFace.js"></script>
<link type="text/css" href="css/main.css" rel="stylesheet" />
</head><body>
<div style="text-align:center; margin-left:auto; margin-right:auto; "><b>鹏哥聊天室</b></div>
<div id="cc"><div id="content"><a href="#" id="clearAll" οnclick="clearAll()" style="float:right">清空记录</a></div><div id="autors"><a href="javascript:;" οnclick="ac('all',this)" class="userck" id="userck">所有人 -共 0 人</a></div>
</div>
<div id="cb">
<span class="an1">请交流吧:</span>
<input type="text" id="sending" value="" style="width: 500px; height: 30px;"/>
<span class="emotion"><img src="arclist/start_face.jpg" style="width:25px;height:25px;margin-bottom: -6px; margin-right: 5px;"/></span>
<input type="button" value="发送" id="send_message" style="width: 100px; height: 38px;">
<input type="hidden" value="" id="cookieName" />
</div>
<script>//获取聊天框对象 用content_div.append(self_content);就能发布信息 var content_div = $("#content"); //设置localStorage对象var storage = window.localStorage;//调用js 时间对象var nowDate = new Date(); //设置cookie方法function setcookie(name,value){ var Days = 1; var exp = new Date(); exp.setTime(exp.getTime() + Days*24*60*60*1000); document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); } //获取cookie方法function getcookie(name){ var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)")); if(arr != null){ return (arr[2]); }else{ return ""; } } //删除cookie方法function delcookie(name){ var exp = new Date(); exp.setTime(exp.getTime() - 1); var cval=getCookie(name); if(cval!=null) document.cookie= name + "="+cval+";expires="+exp.toGMTString(); } //js获取当前时间方法(可传时间戳参数)function getNowFormatDate(timestamp = null) {if(timestamp){var date = new Date(timestamp);}else{var date = new Date();}var seperator1 = "-";var seperator2 = ":";var month = date.getMonth() + 1;var strDate = date.getDate();var strHours = date.getHours();var strMinutes = date.getMinutes();var strSeconds = date.getSeconds();if (month >= 1 && month <= 9) {month = "0" + month;}if (strDate >= 0 && strDate <= 9) {strDate = "0" + strDate;}if (strHours >= 0 && strHours <= 9) {strHours = "0" + strHours;}if (strMinutes >= 0 && strMinutes <= 9) {strMinutes = "0" + strMinutes;}if (strSeconds >= 0 && strSeconds <= 9) {strSeconds = "0" + strSeconds;}var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate+ " " + strHours + seperator2 + strMinutes+ seperator2 + strSeconds;return currentdate;}$(function(){if(!getcookie("tourist")){var tourist=prompt("请输入您的名字","");if(tourist)//如果返回的有内容{setcookie("tourist",tourist);$("#socketName").val(tourist);alert("欢迎您:"+ tourist);}}else{var tourist = getcookie("tourist");alert("欢迎您回来:"+ tourist);}//在登陆时候记录下登陆时间-记录到localstorage中,然后根据失效时间 是否删除所有的localhostStorage数据if(storage.getItem("nowTime")){if(nowDate.getTime() - storage.getItem("nowTime") <= (1000*60*60*24)){var ever_timestamp = parseInt(storage.getItem("nowTime")); //这块要用parseInt函数解析一个字符串,并返回一个整数//调用js 根据时间戳返回标准时间方法var format_time = getNowFormatDate(ever_timestamp);//var format_time = formatDate(storage.getItem("nowTime"));var self_content = " <a class=\"content_tourist\">"+getcookie("tourist")+"</a>曾来到了聊天室,时间为";self_content += "<span class=\"content_nowtime\">["+format_time+"]</span><br>";content_div.append(self_content); }else{storage.removeItem(getcookie("tourist")+"--message");}}//storage.setItem("nowTime",nowDate.getTime());//alert(nowDate.getTime());//websocket = new WebSocket("ws://localhost:3000");var my_websocket = io.connect('ws://localhost:3000');//js获取当前时间var NowDateTime = getNowFormatDate();console.log(my_websocket);my_websocket.on('connect',function(){my_websocket.emit("login",tourist);my_websocket.on('login_message',function(message){//刚进聊天室时候在聊天框显示某某进入聊天室console.log(message);//每次登陆先删除右边栏所有的用户$("#userck").siblings().remove();scrollWindow()var self_content = "<span class=\"content_nowtime\">["+NowDateTime+"]</span>";self_content += " <a class=\"content_tourist\">"+message.user_now+"</a>来到了聊天室:<br><br>";content_div.append(self_content); //在右侧观众栏添加刚登陆的游客var ParentTourist = $("#autors"); for (i in message.user_array){var SonTourist = "<a class=\"userck\">"+message.user_array[i]+"</a>";ParentTourist.append(SonTourist); }var touristCount = "所有人-共 "+message.user_count+" 人";$("#userck").text(touristCount);});my_websocket.on('message',function(msg){//在聊天框添加聊天的记录sendTime = msg.send_time;username = msg.username;tourist_message = replace_em(msg.content);console.log(msg);if(getcookie("tourist") == username){var self_content = "<div class=\"receiver\">";self_content += "<div><img src=\"arclist/online_chat_face.jpg\" style=\"width:50px;height:50px\"></div>";self_content += "<div><div class=\"right_triangle\"></div>";self_content += "<p class=\"receiver_name_r\">"+username+"</p>";self_content += "<span>"+tourist_message+"</span>";self_content += "</div></div><br>";self_content += "<div class=\"clear\"></div>";/*var self_content = "<span class=\"content_nowtime\">["+sendTime+"]</span>";self_content += " <a class=\"content_tourist\">"+username+"</a>说:";self_content += tourist_message+"<br>";*/ }else{var self_content = "<div class=\"sender\">";self_content += "<div><img src=\"arclist/online_chat_face.jpg\" style=\"width:50px;height:50px\"></div>";self_content += "<div><div class=\"left_triangle\"></div>";self_content += "<p class=\"receiver_name_l\">"+username+"</p>";self_content += "<span>"+tourist_message+"</span>";self_content += "</div></div>";self_content += "<div class=\"clear\"></div>";/*var self_content = "<span class=\"content_nowtime\">["+sendTime+"]</span>";self_content += " <a class=\"content_tourist\">"+username+"</a>说:";self_content += tourist_message+"<br>";*/ }content_div.append(self_content); scrollWindow()//并加聊天记录添加到localStorage中,用来在用户再次登陆时候体现上次登录的内容var storageKey = getcookie("tourist")+"--message";//storage.setItem(storageKey,message);});//关闭窗口后触发用户退出功能 window.onunload = onunload_handler;function onunload_handler(){my_websocket.emit("logout",tourist);}my_websocket.on('logout_message',function(message){$("#userck").siblings().remove();var self_content = "<span class=\"content_nowtime\">["+NowDateTime+"]</span>";self_content += " <a class=\"content_tourist\">"+message.user_now+"</a>退出了聊天室:<br>";content_div.append(self_content); //在右侧观众栏添加刚登陆的游客var ParentTourist = $("#autors"); for (i in message.user_array){var SonTourist = "<a class=\"userck\">"+message.user_array[i]+"</a>";ParentTourist.append(SonTourist); }var touristCount = "所有人-共 "+message.user_count+" 人";$("#userck").text(touristCount);});//赋予输入框enter按键发送消息的功能$(document).keypress(function(e){var self_message = $("#sending").val();if(e.keyCode == 13 && self_message){var content_div = $("#content"); var NowDateTime = getNowFormatDate();if(self_message){var data = {username : tourist,content : self_message,send_time: NowDateTime}my_websocket.emit("message",data);$("#sending").val("") ;}else{alert("不能发送空消息");}}});$("#sending").keypress(function(e){var tourist = getcookie("tourist");if(e.keyCode == 13){var content_div = $("#content"); var self_message = $("#sending").val();var NowDateTime = getNowFormatDate();if(self_message){var data = {username : tourist,content : self_message,send_time: NowDateTime}my_websocket.emit("message",data);$("#sending").val("") ;}else{alert("不能发送空消息");}}});//发送按钮点击发送功能$("#send_message").click(function(){var tourist = getcookie("tourist");var content_div = $("#content"); var self_message = $("#sending").val();var NowDateTime = getNowFormatDate();if(self_message){var data = {username : tourist,content : self_message,send_time: NowDateTime}my_websocket.emit("message",data);$("#sending").val("") ;}else{alert("不能发送空消息");}});});$('.emotion').qqFace({id : 'facebox', assign:'sending', path:'arclist/' //表情存放的路径});});
//正则替换表情
function replace_em(str){str = str.replace(/\</g,'<');str = str.replace(/\>/g,'>');str = str.replace(/\n/g,'<br/>');str = str.replace(/\[em_([0-9]*)\]/g,'<img src="arclist/$1.gif" border="0" />');return str;
}
//将信息放在滚动条最下面
function scrollWindow(){var t = document.getElementById('content');t.scrollTop = t.scrollHeight;
}
function clearAll()
{$("content").html("");var newHtml = "<a href=\"#\" οnclick=\"clearAll()\" id=\"clearAll\" style=\"float:right\">清空记录</a>";$("#content").html(newHtml);
}
</script>
</body>
</html>
服务器端 的源码:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);app.get('/',function(req,res){res.send('<h1>Welcome Realtime Server</h1>');
});var userArr = new Array();var userCount = 0;
io.on('connection',function(socket)
{console.log('a user connected');socket.on('login',function(obj){//判断是否是新用户登录 indexOf是js 判断数组是否包含一个元素的函数 大于0表示包含 -1表示不包含if(userArr.indexOf(obj) == '-1'){userArr.push(obj);userCount ++;}var login_message ={user_array : userArr,user_count : userCount,user_now : obj}console.log(login_message);//将所有用户登录的信息发给所有用户io.sockets.emit('login_message',login_message);});socket.on('message',function(msg){console.log('接收到',msg);io.sockets.emit('message',msg);});socket.on('logout',function(obj){console.log(obj+'已退出');//判断是否是新用户登录 indexOf是js 判断数组是否包含一个元素的函数 大于0表示包含 -1表示不包含if(userArr.indexOf(obj) >= '0'){for(var i= 0;i<userArr.length;i++){if(userArr[i] == obj){//1. splice(1,1) -删除第二个元素。////第一个 1 是位置, 位置从0 开始;////第二个1 是个数, 删除一个元素。userArr.splice(i,1);}}userCount --;}var logout_message ={user_array : userArr,user_count : userCount,user_now : obj}console.log("logout");console.log(logout_message);socket.broadcast.emit('logout_message',logout_message);});
});
http.listen(3000,function(){console.log('listening on *:3000');
});
websocket以及nodejs联手打造的类qq群聊天室 教程 附 原代码相关推荐
- 使用nodejs+Socket打造P2P实现多人聊天室
- java qq聊天界面_【附源码】用Java写了一个类QQ界面聊天小项目,可在线聊天!...
原标题:[附源码]用Java写了一个类QQ界面聊天小项目,可在线聊天! 目录: 1.功能实现 2.模块划分 3.使用到知识 4.部分代码实现 5.运行例图 1.功能实现 1.修改功能(密码.昵称.个性 ...
- 最新引流技巧:利用QQ秀聊天室日引1000+IP
现在已经不是"酒香不怕巷子深"的时代了,我们的网站或产品再好,也需要用户来发现,不然,都是空谈.今天给大家分享一个最新的引流方式,希望对大家有帮助,只要你肯做,日引流1000+IP ...
- Nodejs+socket.io 搭建个人的网页聊天室
Nodejs+socket.io 搭建个人的网页聊天室 最近看到别人搭建了自己的实时聊天室便产生了兴趣,于是乎自己也着手搭建了一个.在socket这里我选用了socket.io这个模块,在网上看了很多 ...
- websocket 学习--简单使用,nodejs搭建websocket服务器,到模拟股票,到实现聊天室
websocket简介: WebSocket协议是 HTML5 开始提供的一种基于TCP的一种新的全双工通讯的网络通讯协议.它允许服务器主动发送信息给客户端. 和http协议的不同?? HTTP 协议 ...
- 基于JavaFX的类QQ的聊天工具
一. 功能描述 现在,聊天工具的普及使得信息传递越来越方便,像QQ与微信这样的聊天工具已经可以说是占据了这个行业的半边天,逐渐成为人们日常生活工作间离不开的工具. 因此本次我基于javafx+网络编程 ...
- 基于Qt的类QQ气泡聊天的界面开发(三)
最近在写IM 聊天界面,想设计出一个类似QQ气泡聊天的样式 使用了几种办法 1:使用Qt下面的QListview来实现QQ类似效果,差强人意 2:使用QWebview加载html css样式来完成,发 ...
- 基于Qt的类QQ气泡聊天的界面开发
最近在写IM 聊天界面,想设计出一个类似QQ气泡聊天的样式 使用了几种办法 1:使用Qt下面的QListview来实现QQ类似效果,差强人意 2:使用QWebview加载html css样式来完成,发 ...
- Fms3和Flex打造在线多人视频会议和视频聊天(附原代码)
Flex,Fms3系列文章导航 Flex,Fms3相关文章索引 本篇是视频聊天,会议开发实例系列文章的第3篇,该系列所有文章链接如下: http://www.cnblogs.com/aierong/a ...
最新文章
- Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意
- WebSocket实战之————GatewayWorker使用笔记例子
- 运维笔记 - Nginx
- 科研|本科来自普通二本的博士3年迎来2篇Nature,创造校史!
- 附加数据库后登陆报错
- php代码审计小技巧
- 共享文件夹只能连接20人_英语正能量 | 快乐可以与人共享,苦难却只能自己坚强...
- C# 一次性获取二维数组中的一维数组数据
- PowerBuilder9.0 安装包及注意事项
- 数据库中左连接、右连接、内连接与外连接的区别和作用
- 一句话木马上传常见的几种方法
- 艾永亮:优衣库,究竟是怎么卖衣服的?
- 神兵利器——敏感文件发现工具
- Android 11.0 修改添加的默认文件夹为9宫格样式
- 数据库存储过程怎么写
- 人类想要拥有金钱、权力、美丽、永生、幸福……但海龟只想做一只海龟
- 对YAML :: LoadFile的未定义引用
- 计算机等级二级公共基础
- 世界上还有人以“厕所”为姓,都知道是哪国人
- 中国电信4g最快服务器IP,中国电信DNS IP地址大全(32个省)