含服务端,客户端,数据库的注册/登录/聊天/在线/离线查看的聊天demo
2024-10-19 02:27:10
用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);
};
最新文章
- servlet的匹配规则,兼谈/与/*
- Zookeeper源码编译为Eclipse工程(转)
- 【1】第一次电话面试---上海EMC
- java多线程系列8-线程的优先级
- struts2文件上传类型的过滤
- PHP学习笔记 - 进阶篇(7)
- ASP.NET中Cookie的使用
- Merlin 的魔力: SpringLayout 管理器
- jQ小图标上下滑动特效
- c# Activex开发之HelloWorld
- :after伪类+content内容生成
- ros中自定义消息 报错 ImportError: No module named em
- Linux基础命令---sysctl修改内核参数
- Your password has expired. To log in you must change it using a client that supports expired passwords.
- c# Windows Service 桌面上显示UI
- POJ 1465 Multiple (BFS,同余定理)
- C/C++预定义宏
- python模块之xlrd,xlwt,读写execl(xls,xlsx)
- sublime text 怎么浏览包
- 记一次阿里云linux病毒清理过程