Express+Socket.io 实现简易聊天室
闲暇之余研究了一下 Socket.io,搭建了一个简易版的聊天室,如有不对之处还望指正,先上效果图:
首先是登录页面:
接下来就是聊天页面:
Socket.IO是Node.js的一个模块,它提供通过WebSocket进行通信的一种简单方式,WebSocket协议很复杂,但是Socket.IO提供了服务器和客户端双方的组件,所以只需要一个模块就可以给应用程序加入对WebSocket的支持,而且还能支持不同的浏览器哦。关于其详细介绍请参考官网SocketIO 官网,这里呢我们还是直接上代码。
首先是创建 Socket 服务, 我们的项目启动文件 bin/www,我们就来修改它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| // bin/www var app = require('../app'); var debug = require('debug')('websocket:server'); var http = require('http');
/** * Get port from environment and store in Express. */
var port = normalizePort(process.env.PORT || '3070'); app.set('port', port);
/** * Create HTTP server. */
var server = http.createServer(app); var io = require('socket.io').listen(server); //创建 socket 服务 io.on('connection',function(socket){ //监听客户端的连接请求 socket.emit('connected',"连接成功"); socket.on('message',function(msg){ //监听客户端发送的消息 console.log(msg); socket.emit('content',msg); // 向客户端发送反馈消息 socket.broadcast.emit('content',msg); // 向所有的已连接客户端进行广播消息 }); }); /** * Listen on provided port, on all network interfaces. */
server.listen(port); server.on('error', onError); server.on('listening', onListening); ... ...
|
在这里我做了一个小的登录控制,也就是 session 的简单使用,具体看下边的路由控制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| // routes/index.js var express = require('express'); var router = express.Router();
/* GET home page. */ router.get('/', function(req, res) { res.render('login'); }); router.post('/login',function(req,res){ var name=req.body.name; req.session.name=name; res.send("success"); }); router.get('/index',function(req,res){ if(req.session.name!=null && req.session.name!=""){ res.render('index',{name:req.session.name}); }else{ res.redirect('/'); } }); module.exports = router;
|
然后接下来创建客户端登录页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| // views/login.html <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>登录简化聊天室</title> <link rel="bookmark" type="image/x-icon" href="images/chat.ico"/> <link rel="shortcut icon" href="images/chat.ico"> <link rel="icon" href="img/images/chat.ico"> <link rel="stylesheet" href="js/bootstrap.css" type="text/css" /> <style> .tips{ font-size: 28px; font-family: "楷体"; padding: 10px; } .contentMain{ width: 600px; height: 500px; position:absolute; left:35%; top:40%; z-index: 999; } </style> </head> <body> <div class="loginImg" style="margin: 4% 0;"> <img src="images/005.jpg" style="width: 100%;"/> </div>
<div class="contentMain"> <div class="row tips">请先输入你在聊天室的昵称 </div> <div class="row form-group"> <span class="col-md-6"> <input type="text" id="name" class="form-control" placeholder="昵称"/> </span> <span class="col-md-3"> <button class="btn btn-default" id="login">确认</button> </span> </div> </div> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/bootstrap.js"></script> <script> $(function(){ $('button').click(function(){ var name=$('#name').val(); $.post('/login',{name:name},function(data){ if(data=="success"){ window.location.href='/index'; } }); }) }); </script> </body> </html>
|
聊天室页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| // views/index.html <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>简化聊天室</title> <link rel="bookmark" type="image/x-icon" href="images/chat.ico"/> <link rel="shortcut icon" href="images/chat.ico"> <link rel="icon" href="img/images/chat.ico"> <link rel="stylesheet" href="js/bootstrap.css" type="text/css" /> <style> body{ font-size: 20px; font-family: "楷体"; } .contentMain{ width: 700px; height: 800px; position:absolute; left:5%; top:6%; z-index: 999; } .welcome{ height: 6%; font-family: "楷体"; font-size:35px; background-color: #d0e9c6; } .chatContent{ height:600px; border-radius: 5px; border: 1px solid #555555; overflow-y: auto; overflow-x: hidden; padding: 5px; margin-bottom: 20px; } .talkString{ margin-top:15px; } .myTalk{ border:1px solid #00B7FF; border-radius: 5px; width: auto; padding: 5px; background-color: #d6e9c6; } #content{ padding:2px 10px 2px 10px; } </style> </head> <body> <div class="welcome" align="center"> 欢迎您: <span id="name"><%=name%></span> </div> <div class="bgImage"> <img src="images/005.jpg" style="width: 100%;height: 100%"/> </div> <div class="contentMain">
<div class="chatContent"> <span>聊天记录:</span> <div id="content"></div> </div> <div class="row"> <span class="col-md-10"> <span class="col-md-2"> 内容:</span> <span class="col-md-10"> <input type="text" id="myWord" class="form-control" placeholder="请输入要发送的内容"/> </span> </span> <span class="col-md-2"> <button class="btn btn-default">发送</button> </span> </div> </div>
<script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/socket.io.js"></script> <script type="text/javascript" src="js/bootstrap.js"></script> <script type="text/javascript" src="js/main.js"></script> </body> </html>
|
最后实现我们客户端的 socket,进行与服务端进行通信:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| // js/main.js $(function(){ var name = $('#name').text(); // 向服务器发起连接请求 var socket = io.connect('http://localhost:3070'); socket.on('connected',function(){ // 监听连接信息 console.log('已连接'); socket.send("系统:"+name+" 连接成功"); // 向客户端发送消息 }); socket.on('content',function(msg){ // 监听服务器发送的消息 var talker=""; var talk=""; var talkString=""; if(msg.indexOf(':')>0){ talker=msg.substring(0,msg.indexOf(':')); if(msg.indexOf("<script>")>0&&msg.indexOf("</script>")>0) { msg = msg.replace("<script>", ""); msg = msg.replace("</script>", ""); } talk=msg.substring(msg.indexOf(':')+1); if(talker==name){ talkString="<div class='row talkString' align='right'>" + "<span class='myTalk'>"+talk+"</span>" + "<span> "+talker+"</span>" + "</div>"; }else{ talkString="<div class='row talkString'>" + "<span>"+talker+": </span>" + "<span class='myTalk'>"+talk+"</span>" + "</div>"; } }else{ talkString="<div class='row'>"+msg+"</div>"; } $('#content').append(talkString); scrollBar(); }); $('button').click(function(){ var myWord=$('#myWord').val();
if(socket){ socket.send(name+":"+myWord); $('#myWord').val(""); scrollBar(); }else{ return; } }); //回车发送消息 document.onkeydown = function(e){ var ev = document.all ? window.event : e; if(ev.keyCode==13) { $('button').click(); } }
function scrollBar(){ $(".chatContent").scrollTop($(".chatContent")[0].scrollHeight); } });
|
至此,我们的主要工作基本上完成了,其实也没有多少东西
- 创建 socket 服务器,监听客户端连接与消息,发送消息、广播消息
- socket客户端向服务器申请连接,发送与监听消息
这次只是做了一个简易的聊天室功能,下次我们加入 redis 的 订阅/发布 模式,完成更复杂更灵活的聊天功能,敬请期待!
项目结构:
控制台信息: