用websocket,mysql,node的写了一个简单聊天的demo

实现了:

  • 注册,登陆功能;
  • 聊天信息广播;
  • 在线/离线状态的查看;

服务端:

主要引用http,fs,mysql,socket.io四个模块

具体实现:

1.数据库:

let db=mysql.createPool({host: '', user: '', password: '', database: ''});

2.http服务:

let httpServer=http.createServer((req, res)=>{
fs.readFile(`www${req.url}`, (err, data)=>{
if(err){
res.writeHeader(404);
res.write('not found');
}else{
res.write(data);
}
res.end();
});
});
httpServer.listen(9090);

3.websocket服务:

let aSock=[];
let wsServer=io.listen(httpServer);
wsServer.on('connection', sock=>{
aSock.push(sock);
let cur_username='';
let cur_userID=0;
//注册
sock.on('reg', (user, pass)=>{
//1.校验数据
if(!regs.username.test(user)){
sock.emit('reg_ret', 1, '用户名不符合规范');
}else if(!regs.password.test(pass)){
sock.emit('reg_ret', 1, '密码不符合规范');
}else{
//2.用户名是否存在
db.query(`SELECT ID FROM user WHERE username='${user}'`, (err, data)=>{
if(err){
sock.emit('reg_ret', 1, '数据库有错误1');
}else if(data.length>0){
sock.emit('reg_ret', 1, '用户名已存在');
}else{
//3.插入
db.query(`INSERT INTO user (username, password, online) VALUES('${user}','${pass}', 0)`, err=>{
if(err){
sock.emit('reg_ret', 1, '数据库有错误2');
}else{
sock.emit('reg_ret', 0, '注册成功');
}
});
}
});
}
}); //登陆
sock.on('login', (user, pass)=>{
console.log(user,pass)
//1.校验数据
if(!regs.username.test(user)){
sock.emit('login_ret', 1, '用户名不符合规范');
}else if(!regs.password.test(user)){
sock.emit('login_ret', 1, '密码不符合规范');
}else{
//2.用户信息
db.query(`SELECT ID,password FROM user WHERE username='${user}'`, (err, data)=>{
if(err){
sock.emit('login_ret', 1, '数据库有错1');
}else if(data.length==0){
sock.emit('login_ret', 1, '此用户不存在');
}else if(data[0].password!=pass){
sock.emit('login_ret', 1, '用户名或密码有误2');
}else{
//3.改在线状态
db.query(`UPDATE user SET online=1 WHERE ID=${data[0].ID}`, err=>{
if(err){
sock.emit('login_ret', 1, '数据库有错3');
}else{
sock.emit('login_ret', 0, '登陆成功');
cur_username=user;
cur_userID=data[0].ID;
}
});
}
});
}
});
//发言
sock.on('msg', txt=>{
if(!txt){
sock.emit('msg_ret', 1, '消息文本不能为空');
}else{
//广播给所有人
aSock.forEach(item=>{
if(item==sock)return; item.emit('msg', cur_username, txt);
}); sock.emit('msg_ret', 0, '发送成功');
}
}); //离线
sock.on('disconnect', function (){
db.query(`UPDATE user SET online=0 WHERE ID=${cur_userID}`, err=>{
if(err){
console.log('数据库有错', err);
} cur_username='';
cur_userID=0; aSock=aSock.filter(item=>item!=sock);
});
});
});

客户端:

1.在head中引入socket的js文件:

<script src="http://localhost:9090/socket.io/socket.io.js" charset="utf-8"></script>

2.在script中创建的socket服务:

let sock=io.connect('ws://localhost:9090/');

3.简单的dom结构:

用户:<input type="text" id="user" /><br>
密码:<input type="password" id="pass" /><br>
<input type="button" value="注册" id="btn1">
<input type="button" value="登陆" id="btn2">
<hr>
<textarea id="txt1" rows="4" cols="80"></textarea>
<input type="button" value="发送" id="btn_send"><br>
<ul id="ul1">
</ul>

4.获取dom:

let cur_username='';
let oBtn1=document.getElementById('btn1');
let oBtn2=document.getElementById('btn2');
let oBtnSend=document.getElementById('btn_send');
let oUl=document.getElementById('ul1');
let oUser=document.getElementById('user');
let oPass=document.getElementById('pass');
let oTxt=document.getElementById('txt1');

5.注册:

sock.on('reg_ret', (code, msg)=>{
if(code){
alert('注册失败,'+msg);
}else{
alert('注册成功');
}
});
oBtn1.onclick=function (){
sock.emit('reg', oUser.value, oPass.value);
};

6.登陆:

sock.on('login_ret', (code, msg)=>{
if(code){
alert('登陆有错,'+msg);
}else{
alert('登陆成功');
cur_username=oUser.value;
}
});
oBtn2.onclick=function (){
sock.emit('login', oUser.value, oPass.value);
};

7.消息:

sock.on('msg_ret', (code, msg)=>{
if(code){
alert('消息发送失败,'+msg);
}else{
let oLi=document.createElement('li');
oLi.className='mine';
oLi.innerHTML=`<h4>${cur_username}</h4><p>${oTxt.value}</p>`;
oUl.appendChild(oLi);
oTxt.value='';
}
});
sock.on('msg', (name, txt)=>{
let oLi=document.createElement('li');
oLi.innerHTML=`<h4>${name}</h4><p>${txt}</p>`;
oUl.appendChild(oLi);
});
oBtnSend.onclick=function (){
sock.emit('msg', oTxt.value);
};

最新文章

  1. servlet的匹配规则,兼谈/与/*
  2. Zookeeper源码编译为Eclipse工程(转)
  3. 【1】第一次电话面试---上海EMC
  4. java多线程系列8-线程的优先级
  5. struts2文件上传类型的过滤
  6. PHP学习笔记 - 进阶篇(7)
  7. ASP.NET中Cookie的使用
  8. Merlin 的魔力: SpringLayout 管理器
  9. jQ小图标上下滑动特效
  10. c# Activex开发之HelloWorld
  11. :after伪类+content内容生成
  12. ros中自定义消息 报错 ImportError: No module named em
  13. Linux基础命令---sysctl修改内核参数
  14. Your password has expired. To log in you must change it using a client that supports expired passwords.
  15. c# Windows Service 桌面上显示UI
  16. POJ 1465 Multiple (BFS,同余定理)
  17. C/C++预定义宏
  18. python模块之xlrd,xlwt,读写execl(xls,xlsx)
  19. sublime text 怎么浏览包
  20. 记一次阿里云linux病毒清理过程

热门文章

  1. yii 1.x 添加 rules 验证url数组
  2. flutter学习之二Material Design设计规范
  3. Express全系列教程之(二):Express的路由以及动态路由
  4. DDoS攻击流量检测方法
  5. 使用vue+elementUI+springboot创建基础后台增删改查的管理页面--(1)
  6. spring 数据库多数据源路由
  7. vscode编译发布exe
  8. JAVA反射机制及理解
  9. 18. C# 转换
  10. Beep函数实现硬件蜂鸣声