socket.io简介
Html5中有这样一个新特性,它引入了websocket。我们可以看到这篇关于websocket内部实现原理的文章。这篇文章告诉我们websocket是无中生有的。根据协议,对数据帧的头部进行分析,建立websocket。虽然代码很短,但是可以很好的体现websocket的原理。
该功能基于TCP连接在浏览器和服务器之间提供双向通道。但是并不是所有的浏览器都支持websocket,所以为了抚平浏览器之间的差异,为开发者提供统一的界面,引入了socket.io模块。在不支持websoket的浏览器中,socket.io可以降级为其他通信方式,比如AJAX长轮询、JSONP Polling等等。模块安装
创建一个新的package.json文件,并在文件中写入以下内容:
{ 'name': 'socketiochatroom ',' version': '0.0.1 ',' dependencies ' : { ' socket . io ' : ' * ',' express ' : ' * ' } } npm install
执行完这句话,节点会从npm下载socket.io和express模块。
-
服务器端实现
在文件夹中添加index.js文件,并在文件中写入以下内容:
/** *竹子于2016年3月31日创作。*/var app=require(' express ')();var http=require('http ')。服务器(app);var io=require(' socket . io ')(http);app.get('/'),function (req,res) { '使用strict ';RES . end(' h1 socket server/h1 ' });/*在线人员*/var online users={ };/*在线人数*/var online counts=0;/*io监视链接的存在,并回调套接字进行套接字监视*/io.on ('connection ',function (socket) {console.log('用户已连接');/*监控新用户加入*/socket.on ('login ',function(user){ ' use strict ';//临时套接字. name为user.userId当用户退出时,将使用socket . name=user . userid;如果/*不存在,请添加*/if(!添加在线用户[用户。userid]=用户。在线用户的用户名。hasownproperty(用户。userid)){//不存在;在线计数;}/*新用户加入,并向客户端监听登录的所有socket实例发送响应。响应内容为对象*/io.emit ('login ',{online users : online users,online counts 3360 online counts,user : user });Console.log(user.userName,‘加入聊天室’);//在服务器控制台打印哪些用户加入了聊天室});/*听用户退出聊天室*/socket.on ('disconnect ',function(){ ' use strict ';if(online users . hasown property(socket . name)){ var user={ userid : socket . name,username : online users[socket . name]};删除OnLine USers[socket . name];online counts-;/*向所有客户端广播用户退出群聊的消息*/io.emit('注销',{在线用户:在线用户,在线计数3360在线计数,用户:用户});Console.log(user.userName,‘退出群聊’);}})/*听完用户发来的消息,我用io广播消息,消息被所有客户端接收显示。请注意,如果客户端自己发送此消息,则应判断接收到的消息是否是自己发送的。因此,在发出时,应将用户的id和信息打包成一个对象,用于广播*/socket.on ('message ',function(obj){ ' use strict ';/*收听用户发送的消息,并将消息广播给所有客户端*/io.emit('message ',obj);Console.log(obj.userName,' said : ',obj . content);});});/* listen 3000 */http . listen(3000,function () { '使用strict ';console.log('侦听3000 ');});运行服务器端程序
节点index.js的输出
监听3000此时在浏览器中打开localhost:3000,得到以下结果:
原因是代码中只为路线设置了以下设置
app.get('/'),function (req,res) { '使用strict ';RES . end(' h1 socket server/h1 ' });服务器主要提供socketio服务,没有设置路由。
客户端的实现
在客户端建立以下目录和文件,其中可以从互联网下载js 3 . min . js。
客户
index.html
在index.html,
!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 ' meta name=' format-detection ' content=' phone=no '/meta name=' format-detection ' content=' email=no '/title 1301群聊/title link rel='样式表type='text/css' href=' ./style。CSS '/脚本src=' http :http://实时。plhwin。com :3000/socket。io/套接字。io。js '/script script src=' http :/js 3。量滴js '/script/headdydiv id=' loginbox ' div style=' width : 260 px;余量: 200像素汽车;'输入你在群聊中的昵称br/br/输入类型=' text ' style=' width:180px占位符='请输入用户名id=' userName ' name=' userName '/input type=' button ' style=' width : 50px;值='提交onclick=' CHAT。usernameSubmit();//div/div div id='聊天框' style=' display : nonediv style='背景: # 3d 3d高度: 28px宽度: 100%;font-size : 12px ' div style='行高: 28pxcolor : # fff span style=' text-align : left;左边距left: 10px'1301群聊/span span style=' float : right;margin-right : 10px ' span id=' show username '/span | a href=' JavaScript :onclick=' CHAT。logout()' style=' color : # fff;'退出/a/span/div/div id=' doc ' div id=' chat ' div id=' message ' class=' message ' div id=' online counts ' style=' background : # efef 4;font-size : 12px页边距-top : 10px;左边距left : 10pxcolor : # 666 '/div/div class=' input-box ' div class=' input ' input type=' text ' maxlength=' 140 ' placeholder='输入聊天内容id=' content ' name=' content '/div class=' action ' button type=' button ' id=' mjr _ send ' onclick=' chat。提交();'提交/button/div/div/div脚本类型=' text/JavaScript ' src=' http :/client.js'/script/body/html在client.js中
/** *竹子于2016年3月31日创作。*//*即时运行函数*/(function () { '使用“严格”;var d=document,w=window,dd=d.documentElement,db=d.body,dc=d.compatMode==='CSS1Compat ',dx=dc?dd : db,ec=encodeURIComponent,p=parseIntw。CHAT={ msgobj :d。getelementbyid(' message '),screenHeight: w.innerHeight?内部高度: dx。内部高度,用户名:为空,用户标识:为空,插座:为空,/*滚动条始终在最底部*/scrollToBottom:函数(){ w.scrollTo(0,这个。msgobj。客户端高度);}, /*此处仅为简单的刷新页面,当然可以做复杂点*/注销:函数(){//this。插座。disconnect();w . top。位置。重载();},submit : function(){ var content=d . getelementbyid(' content ').价值;如果(内容!=' '){ var obj={ userid : this。userid,userName: this.userName,content : content };//如在服务器端代码所说,此对象就行想要发送的信息和发送人组合成为对象一起发送this.socket.emit('message ',obj);d.getElementById('content ').值=' ';}返回false},/**客户端根据时间和随机数生成身份证,聊天用户名称可以重复*/genUid:函数(){返回新日期()。getTime()“”数学。地板(数学。random()* 889 100);}, /*更新系统信息主要是在客户端显示当前在线人数,在线人列表等,当有新用户加入或者旧用户退出群聊的时候做出页面提示。
*/updateSysMsg:函数(o,action){ var在线用户=o .在线用户;var在线计数=o .在线计数;var用户=o.user//更新在线人数var userHtml=var分隔符=' ';针对(在线用户中的定义变量键){ if(在线用户。hasown属性(键)){用户html=分隔符在线用户[密钥];分隔符=',';} } //插入在线人数和在线列表d.getElementById('onLineCounts ').innerHTML='当前共有'在线计数'在线列表:' userHtml//添加系统消息var html=html=' div class=' msg _ system html=user . usernamehtml=(action==' log in ')?'加入了群聊' : '退出了群聊;html='/div ';var section=d . CreateElement(' section ');' section.className '系统' J-mjrlinkWrap J-cutMsg ';section . innerhtml=html this . msgobj . appendchild(节);这个。scroltobottom();}, /*用户提交用户名后,将loginbox设置为不显示,将聊天室设置为显示*/userNameSubmit:函数(){ var userName=d . getelementbyid(' userName ').价值;如果(用户名!=' '){ d . getelementbyid(' userName ').值=' ';d . getelementbyid(' loginbox ')。风格。显示='无';d . getelementbyid(' chatbox ')。风格。display=' blockthis.init(用户名);//调用初始化方法}返回false},//用户初始化init:函数(用户名){ //随机数生成uid这个。userid=this。genu id();this.userName=用户名;d.getElementById('showUserName ').innerHTML=this . username//[newpidian]|[退出]这个。滚动到底部();//连接socketIO服务器纽皮迪安的互联网协议(互联网协议)地址这个。socket=io。连接(' 192。168 .3 .15533603000 ');//向服务器发送某用户已经登录了this.socket.emit('login ',{userId: this.userId,username : this。username });//监听来自服务器的登录,即在客户端socket.emit('login ')发送后,客户端就会收到来自服务器的//io.emit('login ',{ onLineUsers: onLineUsers,onLineCounts: onLineCounts,user : user });/*监听到有用户注册了,更新信息*/this.socket.on('login ',function (o) { //更新系统信息CHAT.updateSysMsg(o,'登录');});/*监听到有用户注销了,更新信息*/this.socket.on('注销,函数(o) { CHAT.updateSysMsg(o,'注销');});//var obj={//userid : this。userid,//userName: this.userName,//content : content/};/*监听到有用户发送消息了*/this.socket.on('message ',function (obj) { //判断消息是不是自己发送的var ISme=(obj。UserID===CHAT。UserID);var content div=' div ' obj。内容'/div ';var userNameDiv=' span ' obj。用户名'/span ';var section=d . create element(' section ');if(ISme){ section。类名=' user部分。inner html=ContentDiv usernameDiv;} else { section。类名=' service部分。innerhtml=userNameDiv内容div} CHAT.msgObj.appendChild(节);聊天。scroltobottom();});} } /*控制键键码值(键码)按键键码按键键码按键键码按键键码退格8 Esc 27右箭头39 -_ 189制表符9空格键32 Dw箭头40。190清除12页向上33插入45 /?191输入13向下翻页34删除46 `~ 192移位16结束35数字锁定144 [{ 219控制17首页36; 186-220备选案文18向左箭头37=187 ]} 221开普洛克20向上箭头38,188 '' 222 * *///通过"回车键"提交用户名d.getElementById('userName ').onkeydown=function(e){ console。日志(e);e=e ||事件;if(e .键码===13){ chat。usernamesubmit();} };//通过"回车键"提交聊天内容d.getElementById('content ').onkey down=function(e){ e=e | | event;if(e . KeyCode===13){ CHAT。submit();} };})();style.css
秘密
运行结果
服务器一直在运行,现在客户端正在运行,得到下图:
新增和pidian两个用户,发送信息和退出,得到如下结果:
以上就是边肖介绍的基于Nodejs和socket.io的多人聊天室的实现。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!