nodejs实现聊天室
来源:互联网 发布:淘宝店图片轮播尺寸 编辑:程序博客网 时间:2024/05/18 11:47
http://download.csdn.net/download/u013401219/8960433
项目结构图
需要安装的模块:express,body-parser,cookie-parser ,ejs,express-session,mysql,socket.io
app.js
var express = require('express'); //引用expressvar crypto = require('crypto'); //加密var path = require('path');var bodyParser = require("body-parser");var app = express();var server = require('http').Server(app);var mysql = require("mysql"); //数据库模块var io = require('socket.io').listen(server); //socket io模块var session = require('express-session'); //如果要使用session,需要单独包含这个模块//连接数据库var connPool = mysql.createPool({ host: '127.0.0.1', //主机 user: 'root', //MySQL认证用户名 password: '123456', //MySQL认证用户密码 port: '3306', //端口号 database: 'sv_chat', //数据库 waitForConnections: true, //当连接池没有连接或超出最大限制时,设置为true且会把连接放入队列 //connectionLimit:10,//连接数限制});/*conn.connect(function(err) { if (err) { console.log('[mysql connect] failed:' + err); return; } console.log('[mysql connect] succeed!');});*///express基本配置app.set('port', 3000);app.set('views', __dirname + '/views');app.set("view engine", "ejs");app.use(bodyParser.urlencoded({ extended: false}));app.use(session({ secret: 'ScumVirus', name: 'sv_chat', //这里的name值得是cookie的name,默认cookie的name是:connect.sid cookie: { maxAge: 3600000 }, //设置maxAge是3600000ms,即1h后session和相应的cookie失效过期 resave: false, saveUninitialized: true,}));app.use(express.static(path.join(__dirname, 'static')));//配置路由//登录页app.get('/', function(req, res) { //res.send('hello world'); //console.log(getTime() + " " + req.ip + " visited."); //var ip = req.ip.substring(req.ip.lastIndexOf(":") + 1); res.redirect('/login');});app.get('/login', function(req, res) { res.sendFile(app.get("views") + '/login.html');});//登录方法 postapp.post('/login', function(req, res) { var name = req.body.name; var pwd = getMD5(req.body.pwd); var ip = req.ip.substring(req.ip.lastIndexOf(":") + 1); var time = getTime(); var resData = {}; getUserById(name, function(obj) { if (pwd == obj.pwd) { var params = [time, ip, obj.id]; updateLoginInfo(params); resData.msg = 0; } else { resData.msg = -1; } //设置session req.session.user = name; res.send(resData); });});//注册页app.get('/register', function(req, res) { res.sendFile(app.get("views") + '/register.html');});//注册方法 postapp.post('/register', function(req, res) { var name = req.body.name; var pwd = getMD5(req.body.pwd); var email = req.body.email; var phone = req.body.phone; var time = getTime(); var params = [name, pwd, email, phone, time]; var resData = {}; addUser(params, function(flag) { if (flag) { resData.msg = 0; } else { resData.msg = -1; } res.send(resData); });});//聊天室首页app.get('/index', function(req, res) { if (req.session.user == undefined) { res.redirect('/login'); } else { res.render("index", { "user": req.session.user }); //res.sendFile(app.get("view") + '/index.html'); }});//监听服务器启动server.listen(app.get('port'), function() { console.log("Express server listening on port " + app.get('port'));});//全局变量var onlineMember = [];//WebSocket连接监听io.on('connection', function(socket) { //socket.emit('open',onlineMember); //通知客户端已连接 // 打印握手信息 // console.log(socket.handshake); // 构造客户端对象 var client = { name: '', } // 对message事件的监听 //登录事件 socket.on('login', function(name) { var time = getTime(); client.name = name; var index = getArrIndex(name,onlineMember); if(index == -1){ onlineMember.push(client.name); console.log(time + " " + client.name + " login"); } var obj = { time: time, author: client.name, text: '', type: 'login', member: onlineMember }; socket.emit('system', obj); socket.broadcast.emit('system', obj); }); //消息事件 socket.on('message', function(msg) { var obj = { time: getTime(), }; obj['msg'] = msg; obj['author'] = client.name; obj['type'] = 'message'; // 返回消息(可以省略) socket.emit('message', obj); // 广播向其他用户发消息 socket.broadcast.emit('message', obj); }); //监听退出事件 socket.on('disconnect', function() { var index = getArrIndex(client.name, onlineMember); if (index > -1) { onlineMember.splice(index, 1); } var time = getTime(); var obj = { time: time, author: client.name, text: '', type: 'loginout', member: onlineMember }; console.log(time + " " + client.name + " loginout"); // 广播用户已退出 socket.broadcast.emit('system', obj); });});//获取当前的时间yyyy-MM-dd HH:ii:ssvar getTime = function() { var date = new Date(); return date.getFullYear() + "-" + tc(date.getMonth() + 1) + "-" + tc(date.getDate()) + " " + tc(date.getHours()) + ":" + tc(date.getMinutes()) + ":" + tc(date.getSeconds());}//不足10的首位补0var tc = function(num) { if (num >= 10) { return num; } else { return "0" + num; }}//根据用户获取用户信息var getUserById = function(name, callback) { //执行SQL语句 var sql = 'select * from sv_user where name=?'; var params = [name]; connPool.query(sql, params, function(err, result) { if (err) { console.log('[SELECT ERROR] - ', err.message); return; } return callback(result[0]); });}//添加新用户var addUser = function(params, callback) { //执行SQL语句 var sql = 'insert into sv_user(`name`,`pwd`,`email`,`phone`,`create_time`) values(?,?,?,?,?)'; connPool.query(sql, params, function(err, result) { if (err) { console.log('[INSERT ERROR] - ', err.message); return callback(false); } else { console.log('INSERT ID:', result.insertId); return callback(true); } });}//更新登录时间和ipvar updateLoginInfo = function(params) { var sql = 'update sv_user set login_time=?,login_ip=? where id=?'; connPool.query(sql, params, function(err, result) { if (err) { console.log('[UPDATE ERROR] - ', err.message); } else { console.log('affectedRows:', result.affectedRows); } });}//获取md5加密后的值var getMD5 = function(str) { var md5 = crypto.createHash('md5'); md5.update(str); var d = md5.digest('hex'); return d;}//获取数组中指定值的下标var getArrIndex = function(str, arr) { var index = -1; for (var i = 0; i < arr.length; i++) { if (arr[i] == str) { index = i; break; } } return index;}
chat.js
$(function() { //建立websocket连接 socket = io.connect('http://localhost:3000'); var userName = $("#user").val(); socket.emit('login', userName); //收到server的系统消息 socket.on('system', function(obj) { if (obj.type === "login") { //登录消息 var msg = '<p><span class="time">' + obj.time + '</span><span class="person">' + obj.author + '</span><span class="msg">进入了聊天室。</span></p>'; $(".chat-panel").append(msg); //刷新在线列表 $("#memer-list").empty(); var member = obj.member; var cnt = member.length; $("#memeber-count").text(cnt); for (var i = 0; i < cnt; i++) { var html = '<li><span class="label label-info user">' + member[i] + '</span></li>'; $("#memer-list").append(html); } } else if (obj.type === "loginout") { //登出消息 var msg = '<p><span class="time">' + obj.time + '</span><span class="person">' + obj.author + '</span><span class="msg">离开了聊天室。</span></p>'; $(".chat-panel").append(msg); //刷新在线列表 $("#memer-list").empty(); var member = obj.member; var cnt = member.length; $("#memeber-count").text(cnt); for (var i = 0; i < cnt; i++) { var html = '<li><span class="label label-info user">' + member[i] + '</span></li>'; $("#memer-list").append(html); } } }); socket.on('message', function(obj) { if (obj.type === "message") { //发送消息 var msg = '<p><span class="time">' + obj.time + '</span><span class="person">' + obj.author + '</span>:<span class="msg">' + obj.msg + '</span></p>'; $(".chat-panel").append(msg); } }); $("#send").on("click", function() { var msg = $("#text").val(); if (msg !== "") { socket.emit('message', msg); $("#text").val(""); } });});
index.ejs
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>SV在线聊天系统</title> <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"> <link rel="stylesheet" type="text/css" href="css/font-awesome.css"> <style type="text/css"> * { font-size: 13px; font-family: cursive; } #header { position: fixed; width: 100%; height: 40px; background:#0f0f0f; border-bottom: 1px solid #ddd; } #header > h4 { margin: 0; padding: 0; font-weight: bold; padding-left: 15px; line-height: 40px; color:#fff; } .online-member-panel { margin: 55px 0 10px 0; width: 100%; padding: 15px; border:1px solid #ddd; border-radius: 10px; overflow-y:auto; box-shadow:0 0 10px #ccc; } .online-member-panel > .header { width:100%; padding-left: 15px; padding-right: 15px; } ul { margin: 10px 0 0 0; padding: 0; list-style: none; } #memer-list > li { float: left; margin-left: 10px; margin-right: 10px; } .chat-panel { margin: 10px auto; width: 100%; height: 300px; padding: 15px; border:1px solid #ddd; border-radius: 10px; overflow-y:auto; } textarea { resize:none; } #send { margin-top: 10px; float:right; } p { color:#ccc; } p > span.time { color:#ccc; margin-right: 10px; } p > span.person { color:#428bca; padding-right: 5px; padding-left: 5px; } p > span.msg { color:#666; } </style></head><body> <div id="header"> <h4>SV在线聊天系统</h4> </div> <div class="row-fluid"> <div class="col-md-2"></div> <div class="col-md-8"> <div class="online-member-panel"> <div class="header"> <span>在线会员:<span id="memeber-count" class="label label-warning">0</span></span> </div> <ul id="memer-list"> <!--<li><span class="label label-info">ScumVirus</span></li>--> </ul> </div> <div class="chat-panel"> <!--<p><span class="time">2015-06-06 06:06:06</span><span class="person">ScumVirus</span>:<span class="msg">233333333333</span></p>--> </div> <div class="form-group"> <textarea class="form-control input-sm" rows="3" id="text"></textarea> <button class="btn btn-success" type="button" id="send">发送消息</button> </div> </div> <div class="col-md-2"></div> <input type="hidden" value="<%=user%>" id="user" /> </div></body><script src="js/jquery-2.1.1.js" type="text/javascript"></script><script src="js/bootstrap.js" type="text/javascript"></script><script src="/socket.io/socket.io.js"></script><script src="js/chat.js" type="text/javascript"></script></html>
login.html
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>SV在线聊天系统</title> <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"> <link rel="stylesheet" type="text/css" href="css/font-awesome.css"> <style type="text/css"> * { font-size: 13px; font-family: cursive; } #login-frame { margin:150px auto; float:none; text-align:center; } .form-group { text-align: center; } .form-control { width:200px; display: initial; } #login-frame > h3 { color:#428bca; } .form-group > button { width: 80px; } .form-group > button:nth-child(2) { margin-left: 15px; } </style></head><body> <div class="container-fluid"> <div class="row-fluid"> <div class="col-md-4" id="login-frame"> <h3>SV在线聊天系统</h3> <div class="form-group"> <input type="text" class="form-control input-sm" placeholder="请输入用户名" id="name" /> </div> <div class="form-group"> <input type="password" class="form-control input-sm" placeholder="请输入密码" id="pwd" /> </div> <div class="form-group"> <button type="button" class="btn btn-success" id="login">登录</button> <button type="button" class="btn btn-danger" id="register">注册</button> </div> </div> </div> </div></body><script src="js/jquery-2.1.1.js" type="text/javascript"></script><script src="js/bootstrap.js" type="text/javascript"></script><script type="text/javascript"> $("#register").on("click",function(){ window.location.href = "/register"; }); $("#login").on("click",function(){ var name = $("#name").val(); var pwd = $("#pwd").val(); if(name == "" || pwd == ""){ alert("用户名和密码不能为空!"); return; } $.post("/login",{ name:name, pwd:pwd, },function(data){ if(data.msg == '0'){ window.location.href = "/index"; }else{ alert("账号或密码错误!"); } },'json'); });</script></html>
register.html
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>SV在线聊天系统</title> <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"> <link rel="stylesheet" type="text/css" href="css/font-awesome.css"> <style type="text/css"> * { font-size: 13px; font-family: cursive; } #login-frame { margin:100px auto; text-align:left; } .form-group > * { display: inline-block; } .form-control { width:200px; display: initial; } .alert { margin: 0 0 0 10px; padding: 5px; } </style></head><body> <div class="container-fluid"> <div class="row-fluid"> <div class="col-md-12" id="login-frame"> <div class="form-group"> <label style="margin-right:2px;">用 户 名:</label> <input type="text" class="form-control input-sm" placeholder="请输入用户名" id="name" /> <div class="alert alert-danger">用户名必须为4-16位的英文字母或数字。</div> </div> <div class="form-group"> <label>密 码:</label> <input type="password" class="form-control input-sm" placeholder="请输入密码" id="pwd" /> <div class="alert alert-danger">密码必须为6-16位。</div> </div> <div class="form-group"> <label>确认密码:</label> <input type="password" class="form-control input-sm" placeholder="请再次输入密码" id="repwd" /> <div class="alert alert-danger">两次输入的密码要一致。</div> </div> <div class="form-group"> <label>邮 箱:</label> <input type="text" class="form-control input-sm" placeholder="请输入邮箱账号" id="email" /> <div class="alert alert-danger">Email格式不正确。</div> </div> <div class="form-group"> <label>手 机:</label> <input type="text" class="form-control input-sm" placeholder="请输入手机号码" id="phone" /> <div class="alert alert-danger">手机号码格式不正确。</div> </div> <div class="form-group"> <button type="button" class="btn btn-success form-control" id="register">注 册</button> </div> </div> </div> </div></body> <script src="js/jquery-2.1.1.js" type="text/javascript"></script> <script src="js/bootstrap.js" type="text/javascript"></script> <script type="text/javascript"> $(".alert").hide(); $("#register").on("click",function(){ $(".alert").hide(); var name = $("#name").val(); var pwd = $("#pwd").val(); var repwd = $("#repwd").val(); var email = $("#email").val(); var phone = $("#phone").val(); if(name.length<4 || name.length>16 || !isName(name)){ $("#name").next().show(); return; }// if(pwd.length<6 || pwd.length>16){// $("#pwd").next().show();// return;// } if(repwd != pwd){ $("#repwd").next().show(); return; } if(!isEmail(email)){ $("#email").next().show(); return; } if(!isPhone(phone)){ $("#phone").next().show(); return; } $.post("/register",{ name:name, pwd:pwd, email:email, phone:phone, },function(data){ if(data.msg == '0'){ alert("注册成功!"); window.location.href = "/"; }else{ alert("注册失败,该用户名可能已被注册!"); } },'json'); }); //验证用户名 function isName(value){ var reg = /^(?=.*[a-z])[a-z0-9]+/ig return reg.test(value); } //验证邮箱 function isEmail(value) { return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value); } //验证手机号 function isPhone(value){ return /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/.test(value); }</script></html>
阅读全文
0 0
- nodejs+nowjs实现聊天室
- nodejs实现聊天室
- HTML5 WebSocket + NodeJs 实现聊天室
- nodejs 基于socket.io实现聊天室
- 用NodeJS实现一个简单的聊天室
- nodejs+socket.io实现校内局域网聊天室
- 利用socket.io实现多人聊天室(基于Nodejs)
- Nodejs做聊天室
- Nodejs入门聊天室
- nodejs+socket.io聊天室
- 聊天室软件设计-nodejs
- nodejs socket.io 聊天室
- NodeJs小试牛刀--聊天室搭建
- 前端之nodejs聊天室
- nodejs多房间web聊天室
- JSP+Nodejs+Socket.IO 聊天室
- nodejs +webSocket 多人聊天室
- 基于NodeJs的局域网聊天室
- xshell连接ubuntu & xshell点击无反应
- hdu 1272 (小希的迷宫)
- 【Scikit-Learn 中文文档 】安装 scikit-learn | ApacheCN
- 安卓 三方百度地图
- Redis数据类型及其实例
- nodejs实现聊天室
- 【Scikit-Learn 中文文档】使用 scikit-learn 介绍机器学习 | ApacheCN
- AMD define函数
- 【操作系统】作业调度的五种算法
- UESTC
- linux-shell高级编程-操作变量串
- ONAP发布“阿姆斯特丹”版本,为网络服务自动化制定标准
- Redis服务器及服务器命令
- 【Scikit-Learn 中文文档】广义线性模型