含服务端,客户端,数据库的注册/登录/聊天/在线/离线查看的聊天demo

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

实现了:

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

服务端:

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

具体实现:

  1. 数据库:
let db=mysql.createPool({host: '', user: '', password: '', database: ''});
  1. 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>
  1. 在script中创建的socket服务:
let sock=io.connect('ws://localhost:9090/');
  1. 简单的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>
  1. 获取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'); 
  1. 注册:
sock.on('reg_ret', (code, msg)=>{
  if(code){
    alert('注册失败,'+msg);
  }else{
    alert('注册成功');
  }
});
oBtn1.onclick=function (){
  sock.emit('reg', oUser.value, oPass.value);
};
  1. 登陆:
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);
};  
  1. 消息:
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);
};
posted @ 2019-03-29 14:59  请叫我卫辰大哥哥  阅读(389)  评论(0编辑  收藏  举报