|
阅读:8313回复:0
express+socket.io打造实时聊天
说点废话:最近公司闲着无聊,做了一个实时聊天。发现bug不断。还好。摸爬滚打一番之后。终于搞定了。后续的功能还在不断完善....
不废话了先上图: 图片:QQ图片20170518110135.png ![]() 图片:QQ截图20170518105920.png ![]() 图片:QQ截图20170518110822.png
先安装sock.io(express就不多说了)注:socket.io分为服务端和客户端 npm install socket.io 服务端:(先建立express的服务模块在建立socket服务模块) 注意:require('./server/node_modules/socket.io').listen(端口号)和app.set("port",9999);是socket.io和express两个不同的端口号,做不一样的事情。前者监听socket后者express。 這里当初入坑太久。一直找不到原因。 网上很多人写的是io = require('socket.io').listen(app),之前也是一样的這样配置。结果发现端口一样两个电脑根本访问不了。localhost却没有问题。 var express=require('./server/node_modules/express'); var app=express(); var io=require('./server/node_modules/socket.io').listen(3000); //存储登陆姓名及唯一ID标识 var clientUsers=[]; // 设置服务器端口 app.set("port",9999); //express 进行配置 app.configure(function(){ app.use(express.static(__dirname+"/client"));//静态资源文件的路径 } ); //拦截地址 app.get('/', function(req, res){ res.redirect("index2.html"); }); //监听服务器 app.listen(app.get("port"),function(req,resp){ console.log("请求来了"); }); //监听客户端连接,回调函数会传递本次连接的socket io.on('connection', function (client) { // 接受客户端消息(YourcustomMessage) client.on('YourcustomMessage', function (data) { console.log('收到客户端消息:', data); }); // 监听socket断开与重连 client.on('disconnect', function () { console.log('你与服务器已经断开连接'); }); }); 客户端:(客户端一个引用了socket.io.js的javscript库 还有就是连接服务器(通过io.connect(‘http://localhost’)) 之后在监听收发消息以及广播消息了) <script src='../js/socket.io.js'></script>引入注意:网上很多人会写localhost:端口号来获取。本人不建议。因为换了端口号忘记更改,后来找Bug会像我一样找本天。而且用IP地址访问一旦端口号不正确就各种错误。反正我是遇到太多。 上代码: var HTML5WebSockets = {}; HTML5WebSockets.socketio = { yoursocket: null, initialize: function () { //建立一个socket连接(页面地址http://192.168.1.16:3000) // HTML5WebSockets.socketio.yoursocket = io.connect('http://192.168.3.165:3000');這是socket.io客户端的发送的端口号。所以要与服务器listen(3000);一样 HTML5WebSockets.socketio.yoursocket =io('ws://192.168.3.165:3000', {transports: ['websocket']}); //注:{transports: ['websocket']}很多人都不回加。我也不是为了加了好玩。看了好半天大神的论坛才知道Bug存在的原因。 //连接服务器 HTML5WebSockets.socketio.yoursocket.on('connect', function () { HTML5WebSockets.socketio.log('<p class="link">你好你已成功连接服务器 </p>'); }); //[广播消息]接收到服务器的消息(此时服务器为广播消息YourMessageResponse name为服务端获取的名称) HTML5WebSockets.socketio.yoursocket.on('YourMessageResponse', function (data,name) { HTML5WebSockets.socketio.log(); $("#log").scrollTop(9999999);//消息置底 给QQ微信一样。超过屏幕的消息总会在最底下 }); //监听socket断开与重连 HTML5WebSockets.socketio.yoursocket.on('disconnect', function () { HTML5WebSockets.socketio.log('<p class="off">你与服务器断开连接</p> '); }); //监听关闭客户端退出聊天(YouDisconnect) HTML5WebSockets.socketio.yoursocket.on('YouDisconnect', function (data) { HTML5WebSockets.socketio.log('<p class="off">***退出了聊天</p> '); }); //处理DOM元素 document.querySelector('#sendCustMes').onclick = function () { HTML5WebSockets.socketio.emitCustomMessageToServer(document.querySelector('#custMes').value); document.querySelector('#custMes').value = ''; }; // $(document).keydown(function (event) { // switch (event.keyCode) { // case 13://回车处理DOM元素 // HTML5WebSockets.socketio.emitCustomMessageToServer(document.querySelector('#custMes').value); // document.querySelector('#custMes').value = ''; // break; // } // return false; // }); }, //客户端发送消息到服务器(YourcustomMessage)客户端→服务端 emitCustomMessageToServer: function (data) { //客户端自己发的消息 HTML5WebSockets.socage">ketio.log(); HTML5WebSockets.socketio.yoursocket.emit('YourcustomMessage', data,name); }, log: function (message) { document.querySelector('#log').innerHTML += message; }, } <div id='log'></div> <div class="btn"> <input type='text' id='custMes' /> <button type='button' id='sendCustMes'></button> </div> 完整代码: 服务端: var express=require('./server/node_modules/express'); var app=express(); var io=require('./server/node_modules/socket.io').listen(3000); //存储登陆姓名及唯一ID标识 var clientUsers=[]; // 设置服务器端口 app.set("port",9999); //express 进行配置 app.configure(function(){ app.use(express.static(__dirname+"/client"));//静态资源文件的路径 } ); //拦截地址 app.get('/', function(req, res){ res.redirect("index2.html"); }); //监听服务器 app.listen(app.get("port"),function(req,resp){ console.log("请求来了"); }); //监听客户端连接,回调函数会传递本次连接的socket io.on('connection', function (client) { // 接受客户端消息(YourcustomMessage) client.on('YourcustomMessage', function (data,name) { console.log('收到客户端消息:', data,name); //给所有客户端发出广播消息emit(发送YourMessageResponse)服务端→客户端 client.broadcast.emit('YourMessageResponse', data ,name); }); // 接受客户端消息(YourcustomMessage_1,登陆姓名) //YourcustomMessage_1 实时消息 client.on('YourcustomMessage_1', function (name_1) { console.log('收到客户端姓名:',name_1); //为了获取客户端传过来的登陆姓名(name_1是全部姓名信息不能作为单个退出记录) clientUsers.push({"ClientID":client.id,"UserName":name_1}); client.broadcast.emit('YourMessageResponse_1',name_1); }); // 监听socket断开与重连 client.on('disconnect', function () { console.log('你与服务器已经断开连接'); //clientID(socket.io会在断开连接时用client.id作为唯一标识) var clientID=client.id; var userName=''; var index=0; //当数组内的ClientID({"ClientID":client.id})==断开时唯一记录的标识 就取userName(***退出了聊天)取出唯一标识的姓名 for(index;index<clientUsers.length;index++){ if(clientUsers[index].ClientID==clientID){ userName=clientUsers[index].UserName; break; } } client.broadcast.emit('YouDisconnect',userName); console.log(userName,'退出了聊天'); //清空退出聊天的客户端信息 clientUsers.splice(index, 1); }); }); 客户端 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="format-detection" content="telephone=no"/> <meta name="format-detection" content="email=no"/> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" name="viewport"> <title>聊天测试demo</title> <link rel="stylesheet" href="../css/index2.css"> <!--<link rel="stylesheet" type="text/css" href="./style.css" />--> <!--IE8以下版本的IE浏览器中加载,目的是让这些低版本的IE浏览器也能处理json,这是一个开源的JS,详见:http://bestiejs.github.io/json3/--> <!--[if lt IE 8]><script src="./json3.min.js"></script><![endif]--> <!--Socket.IO提供的客户端JS文件,在前面安装服务端的步骤中,当npm安装完socket.io并搭建起WebServer后,这个JS文件就可以正常访问了。--> <!--<script src="http://localhost:3000/socket.io/socket.io.js"></script>--> <script src='../js/socket.io.js'></script> <script type="text/javascript" src="../js/jquery-1.11.3.js"></script> <!--<script type="text/javascript" src="./../js/client.js"></script>--> </head> <body> <script> // 初始化页面登陆信息 name = prompt("请输入你的姓名:",""); //获取当前时间 function show(){ var mydate = new Date(); var str = "" + mydate.getFullYear() + "-"; str += (mydate.getMonth()+1) + "-"; str += mydate.getDate() + " "; str += mydate.getHours() + ":"; str += mydate.getMinutes() + ":"; str += mydate.getSeconds(); return str; } //WebSockets服务 var HTML5WebSockets = {}; HTML5WebSockets.socketio = { yoursocket: null, initialize: function () { //建立一个socket连接(页面地址http://192.168.1.16:3000) // HTML5WebSockets.socketio.yoursocket = io.connect('http://192.168.3.165:3000'); HTML5WebSockets.socketio.yoursocket =io('ws://192.168.3.165:3000', {transports: ['websocket']}); //连接服务器 HTML5WebSockets.socketio.yoursocket.on('connect', function () { HTML5WebSockets.socketio.log('<p class="link">你好 '+name+' 你已成功连接服务器 '+show()+'</p>'); }); //[广播消息]接收到服务器的消息(此时服务器为广播消息YourMessageResponse name为服务端获取的名称) HTML5WebSockets.socketio.yoursocket.on('YourMessageResponse', function (data,name) { HTML5WebSockets.socketio.log('<span class="name"><span class="broadcastName">'+name+'</span><span class="broadcastMessage">'+data+'</span></span></br>'); $("#log").scrollTop(9999999);//消息置底 }); //[广播消息]接收到服务器的消息(获取服务端登陆姓名) HTML5WebSockets.socketio.yoursocket.on('YourMessageResponse_1', function (name_1) { HTML5WebSockets.socketio.log('<p class="access">'+name_1+'加入了聊天 '+show()+'</p>'); $("#log").scrollTop(9999999);//消息置底 }); //监听socket断开与重连 HTML5WebSockets.socketio.yoursocket.on('disconnect', function () { HTML5WebSockets.socketio.log('<p class="off">你与服务器断开连接</p> '); }); //监听关闭客户端退出聊天(YouDisconnect) HTML5WebSockets.socketio.yoursocket.on('YouDisconnect', function (data) { HTML5WebSockets.socketio.log('<p class="off">'+data+'退出了聊天</p> '); }); //处理DOM元素 document.querySelector('#sendCustMes').onclick = function () { HTML5WebSockets.socketio.emitCustomMessageToServer(document.querySelector('#custMes').value); document.querySelector('#custMes').value = ''; }; // $(document).keydown(function (event) { // switch (event.keyCode) { // case 13://回车处理DOM元素 // HTML5WebSockets.socketio.emitCustomMessageToServer(document.querySelector('#custMes').value); // document.querySelector('#custMes').value = ''; // break; // } // return false; // }); //获取初始登陆输入的name(因为获取初始化登陆name名称不需要点击之后进行) HTML5WebSockets.socketio.emitCustomMessageToServer_1(name); }, //客户端发送消息到服务器(YourcustomMessage)客户端→服务端 emitCustomMessageToServer: function (data) { //客户端自己发的消息 HTML5WebSockets.socketio.log( '<span class="name_1"><span class="myMessage">'+data+'</span><span class="myName">'+name+'</span></span> '); HTML5WebSockets.socketio.yoursocket.emit('YourcustomMessage', data,name); }, log: function (message) { document.querySelector('#log').innerHTML += message; }, //客户端发送消息到服务器(YourcustomMessage)客户端→服务端(emitCustomMessageToServer_1是初始name用于显示 {‘**加入聊天’}) //不需要点击进行发送到服务器 emitCustomMessageToServer_1: function (name_1) { HTML5WebSockets.socketio.yoursocket.emit('YourcustomMessage_1',name_1); } } </script> <div id='log'></div> <div class="btn"> <input type='text' id='custMes' /> <button type='button' id='sendCustMes'></button> </div> <script> HTML5WebSockets.socketio.initialize(); </script> <script type="text/javascript" src="../js/index2.js"></script> </body> </html> CSS: body,html{ height:100%; margin: 0 auto; } #log{ overflow: auto; height: 85%; } .link{ font-size: 12px; text-align: center; border-bottom: 1px solid #EDECEA; padding-bottom: 5px; color: gray; box-shadow: 0px 3px 7px #FAFAFA; } .access{ font-size: 12px; text-align: center; border-bottom: 1px solid #EDECEA; padding-bottom: 5px; color: gray; } /*广播消息*/ .name{ display: inline-block; width: 98%; font-size: 14px; color: #3DBA98; line-height: 26px; margin-top: 10px; margin-left: 5px; } .broadcastMessage{ color: white; margin-left: 5px; margin-right: 13px; padding: 5px 10px 5px 10px; display: inline-block; border-radius: 5px; background-color: #3DBA98; box-shadow: 0px 1px 20px #DDDDDD; max-width: 90%; } /*我的消息*/ .name_1{ display: inline-block; text-align: right; font-size: 14px; color: #3DBA98; line-height: 26px; margin-top: 10px; margin-right: 5px; float: right; width: 100%; margin-bottom: 10px; } .myMessage{ color: black; margin-left: 10px; margin-right: 5px; padding: 5px 10px 5px 10px; display: inline-block; border-radius: 5px; background-color: white; box-shadow: 0px 1px 10px #DDDDDD; max-width: 89%; } .btn{ position: absolute; bottom: 10px; left: 0; margin-top: 10px; width: 100%; border-top: 1px solid #3DBA98; padding-top: 5px; background: white; } .btn input{ width: 80%; height: 30px; border: none; margin-left: 5px; } @font-face { font-family: iconfont; src: url(../font/iconfont.woff); } .btn button{ border:none; height: 50px; width: 50px; border-radius:50px; font-family: iconfont; font-size: 30px; text-align: center; color: white; background: #3DBA98; } .off{ font-size: 12px; text-align: center; padding-bottom: 5px; color: #3DBA98; } img及font就不上传了。 思考:由于时间关系没有做更多的功能,本来是想做发送图片视频,及存储聊天记录到数据库,登陆注册模块。群聊及私聊。看来还得加班加点。好吧。第一次发這么长的贴。就算勉励自己吧。 |
|
