基于Nodejs利用socket.io实现多人聊天室
网络编程 2021-07-04 19:20www.168986.cn编程入门
这篇文章讲述了websocket无到有,根据协议,分析数据帧的头,进行构建websocket。虽然代码短,但可以很好地体现websocket的原理。对nodejs利用socket 实现多人聊天室功能感兴趣的朋友一起看看吧
socket.io简介
在Html5中存在着这样的一个新特性,引入了websocket,关于websocket的内部实现原理可以看这篇文章,这篇文章讲述了websocket无到有,根据协议,分析数据帧的头,进行构建websocket。虽然代码短,但可以很好地体现websocket的原理。
,这个特性提供了浏览器端和服务器端的基于TCP连接的双向通道。并不是所有的浏览器都支持websocket特性,故为了磨平浏览器间的差异,为开发者提供统一的接口,引入了socket.io模块。在不支持websoket的浏览器中,socket.io可以降级为其他的通信方式,比如有AJAX long polling ,JSONP Polling等。
模块安装
新建一个package.json文件,在文件中写入如下内容
{ "name": "socketiochatroom", "version": "0.0.1", "dependencies": { "socket.io": "", "express":"" } }
npm install
执行完这句,node将会从npm处下载socket.io和express模块。
-
服务器端的实现
在文件夹中添加index.js文件,并在文件中写入如下内容
/ Created by bamboo on 2016/3/31. / var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); app.get('/', function (req, res) { "use strict"; res.end("<h1>socket server</h1>") }); /在线人员/ var onLineUsers = {}; / 在线人数/ var onLineCounts = 0; /io监听到存在链接,此时回调一个socket进行socket监听/ io.on('connection', function (socket) { console.log('a user connected'); /监听新用户加入/ socket.on('login', function (user) { "use strict"; //暂存socket.name 为user.userId;在用户退出时候将会用到 socket.name = user.userId; /不存在则加入 / if (!onLineUsers.hasOwnProperty(user.userId)) { //不存在则加入 onLineUsers[user.userId] = user.userName; onLineCounts++; } /一个用户新加入,向所有客户端监听login的socket的实例发送响应,响应内容为一个对象/ io.emit('login', {onLineUsers: onLineUsers, onLineCounts: onLineCounts, user: user}); console.log(user.userName, "加入了聊天室");//在服务器控制台中打印么么么用户加入到了聊天室 }); /监听用户退出聊天室/ socket.on('disconnect', function () { "use strict"; if (onLineUsers.hasOwnProperty(socket.name)) { var user = {userId: socket.name, userName: onLineUsers[socket.name]}; delete onLineUsers[socket.name]; onLineCounts--; /向所有客户端广播该用户退出群聊/ io.emit('logout', {onLineUsers: onLineUsers, onLineCounts: onLineCounts, user: user}); console.log(user.userName, "退出群聊"); } }) /监听到用户发送了消息,就使用io广播信息,信息被所有客户端接收并显示。注意,如果客户端自己发送的也会接收到这个消息,故在客户端应当存在这的判断,是否收到的消息是自己发送的,故在emit时,应该将用户的id和信息封装成一个对象进行广播/ socket.on('message', function (obj) { "use strict"; /监听到有用户发消息,将该消息广播给所有客户端/ io.emit('message', obj); console.log(obj.userName, "说了:", obj.content); }); }); /监听3000/ http.listen(3000, function () { "use strict"; console.log('listening 3000'); });
运行服务器端程序
node index.js
输出
listening 3000
此时在浏览器中打开localhost:3000会得到这样的结果
原因是在代码中只对路由进行了如下设置
app.get('/', function (req, res) { "use strict"; res.end("<h1>socket server</h1>") });
服务器端主要是提供socketio服务,并没有设置路由。
客户端的实现
在客户端建立如下的目录和文件,其中json3.min.js可以从网上下载到。
client
- - - client.js
- - - index.html
- - - json3.min.js
- - - style.css
在index.html中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="format-detection" content="telephone=no"/> <meta name="format-detection" content="email=no"/> <title>1301群聊</title> <link rel="stylesheet" type="text/css" href="./style.css"/> <script src="http://realtime.plhwin.:3000/socket.io/socket.io.js"></script> <script src="./json3.min.js"></script> </head> <body> <div id="loginbox"> <div style="width: 260px;margin: 200px auto;"> 输入你在群聊中的昵称 <br/> <br/> <input type="text" style="width:180px;" placeholder="请输入用户名" id="userName" name="userName"/> <input type="button" style="width: 50px;" value="提交" onclick="CHAT.userNameSubmit();"/> </div> </div> <div id="chatbox" style="display: none;"> <div style="background: #3d3d3d;height: 28px;width: 100%;font-size: 12px"> <div style="line-height: 28px;color:#fff;"> <span style="text-align: left;margin-left: 10px;">1301群聊</span> <span style="float: right;margin-right: 10px"><span id="showUserName"></span>| <a href="javascript:;" onclick="CHAT.logout()" style="color: #fff;">退出</a></span> </div> </div> <div id="doc"> <div id="chat"> <div id="message" class="message"> <div id="onLineCounts" style="background: #EFEFF4; font-size: 12px;margin-: 10px;margin-left: 10px;color: #666;"> </div> </div> <div class="input-box"> <div class="input"> <input type="text" maxlength="140" placeholder="输入聊天内容 " id="content" name="content" > </div> <div class="action"> <button type="button" id="mjr_send" onclick="CHAT.submit();">提交</button> </div> </div> </div> </div> </div> <script type="text/javascript" src="./client.js"></script> </body> </html>
在client.js中
/ Created by bamboo on 2016/3/31. / /即时运行函数/ (function () { "use strict"; var d = document, w = window, dd = d.documentElement, db = d.body, dc = d.patMode === "CSS1Compat", dx = dc ? dd : db, ec = encodeURIComponent, p = parseInt; w.CHAT = { msgObj: d.getElementById("message"), screenHeight: w.innerHeight ? w.innerHeight : dx.innerHeight, userName: null, userId: null, socket: null, /滚动条始终在最底部/ scrollToBottom: function () { w.scrollTo(0, this.msgObj.clientHeight); }, /此处仅为简单的刷新页面,可以做复杂点/ logout: function () { // this.socket.disconnect(); w..location.reload(); }, submit: function () { var content = d.getElementById('content').value; if (content != '') { var obj = { userId: this.userId, userName: this.userName, content: content }; //如在服务器端代码所说,此对象就行想要发送的信息和发送人组合成为对象一起发送。 this.socket.emit('message', obj); d.getElementById('content').value = ''; } return false; }, /客户端根据时间和随机数生成ID,聊天用户名称可以重复/ genUid: function () { return new Date().getTime() + "" + Math.floor(Math.random() 889 + 100); }, /更新系统信息 主要是在客户端显示当前在线人数,在线人列表等,当有新用户加入或者旧用户退出群聊的时候做出页面提示。/ updateSysMsg: function (o, action) { var onLineUsers = o.onLineUsers; var onLineCounts = o.onLineCounts; var user = o.user; //更新在线人数 var userHtml = ''; var separator = ''; for (var key in onLineUsers) { if (onLineUsers.hasOwnProperty(key)) { userHtml += separator + onLineUsers[key]; separator = '、'; } } //插入在线人数和在线列表 d.getElementById('onLineCounts').innerHTML = '当前共有' + onLineCounts + "在线列表 " + userHtml; //添加系统消息 var html = ''; html += '<div class="msg_system">'; html += user.userName; html += (action === "login") ? "加入了群聊" : "退出了群聊"; html += '</div>'; var section = d.createElement('section'); section.className = 'system J-mjrlinkWrap J-cutMsg'; section.innerHTML = html; this.msgObj.appendChild(section); this.scrollToBottom(); }, /用户提交用户名后,将loginbox设置为不显示,将chatbox设置为显示/ userNameSubmit: function () { var userName = d.getElementById('userName').value; if (userName != '') { d.getElementById('userName').value = ''; d.getElementById('loginbox').style.display = 'none'; d.getElementById('chatbox').style.display = 'block'; this.init(userName);//调用init方法 } return false; }, //用户初始化 init: function (userName) { //随机数生成uid this.userId = this.genUid(); this.userName = userName; d.getElementById('showUserName').innerHTML = this.userName;//[newpidian]|[退出] this.scrollToBottom(); //连接socketIO服务器,newpidian的IP地址 this.socket = io.connect('192.168.3.155:3000'); //向服务器发送某用户已经登录了 this.socket.emit('login', {userId: this.userId, userName: this.userName}); //监听来自服务器的login,即在客户端socket.emit('login ')发送后,客户端就会收到来自服务器的 // io.emit('login', {onLineUsers: onLineUsers, onLineCounts: onLineCounts, user: user}); /监听到有用户login了,更新信息/ this.socket.on('login', function (o) { //更新系统信息 CHAT.updateSysMsg(o, 'login'); }); /监听到有用户logout了,更新信息/ this.socket.on('logout', function (o) { CHAT.updateSysMsg(o, 'logout'); }); //var obj = { // userId: this.userId, // userName: this.userName, // content: content /
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程