用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);
};

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

  1. TCP/IP网络编程之基于UDP的服务端/客户端

    理解UDP 在之前学习TCP的过程中,我们还了解了TCP/IP协议栈.在四层TCP/IP模型中,传输层分为TCP和UDP这两种.数据交换过程可以分为通过TCP套接字完成的TCP方式和通过UDP套接字完 ...

  2. TCP/IP网络编程之基于TCP的服务端/客户端(一)

    理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流(stream)的套接字.TCP是Transmissi ...

  3. 手写内网穿透服务端客户端(NAT穿透)原理及实现

    Hello,I'm Shendi. 这天心血来潮,决定做一个内网穿透的软件. 用过花生壳等软件的就知道内网穿透是个啥,干嘛用的了. 我们如果有服务器(比如tomcat),实际上我们在电脑上开启了服务器 ...

  4. react服务端/客户端,同构代码心得

    FKP-REST是一套全栈javascript框架   react服务端/客户端,同构代码心得 作者:webkixi react服务端/客户端,同构代码心得 服务端,客户端同构一套代码,大前端的梦想, ...

  5. 基于JAX-WS的Web Service服务端/客户端 ;JAX-WS + Spring 开发webservice

    一.基于JAX-WS的Web Service服务端/客户端 下面描述的是在main函数中使用JAX-WS的Web Service的方法,不是在web工程里访问,在web工程里访问,参加第二节. JAX ...

  6. JAVA WEBSERVICE服务端&客户端的配置及调用(基于JDK)

    前言:我之前是从事C#开发的,因公司项目目前转战JAVA&ANDROID开发,由于对JAVA的各种不了解,遇到的也是重重困难.目前在做WEBSERVICE提供数据支持,看了网上相关大片的资料也 ...

  7. NTP时间同步 服务端 客户端 自动化安装配置

    NTP时间同步 服务端 客户端 自动化安装配置 原创内容 http://www.cnblogs.com/elvi/p/7657994.html #!/bin/sh #运行环境 centos6.cent ...

  8. chrony时间同步 服务端 客户端 安装配置

    chrony时间同步 服务端 客户端 安装配置 原创内容http://www.cnblogs.com/elvi/p/7658021.html #!/bin/sh #运行环境 centos7 #chro ...

  9. eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(二)

    eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(二) 接上篇博客,本篇博客主要包含两个内容: 4.使用Android studio创建webservice客 ...

随机推荐

  1. 推送测试,生产环境无法打印log获取deviceToken,可以通过弹窗获取deviceToken

    z- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:( ...

  2. 2PC/3PC/Paxos

    在分布式系统中,一个事务可能涉及到集群中的多个节点.单个节点很容易知道自己执行的事务成功还是失败,但因为网络不可靠难以了解其它节点的执行状态(可能事务执行成功但网络访问超时). 若部分节点事务执行失败 ...

  3. CF451E Devu and Flowers 数论

    正解:容斥+Lucas定理+组合数学 解题报告: 传送门! 先mk个我不会的母函数的做法,,, 首先这个题的母函数是不难想到的,,,就$\left (  1+x_{1}^{1}+x_{1}^{2}+. ...

  4. 记AOP概念理解

    OOD/OOP面向名词领域,AOP面向动词领域. 应用举例 假设有在一个应用系统中,有一个共享的数据必须被并发同时访问,首先,将这个数据封装在数据对象中,称为Data Class,同时,将有多个访问类 ...

  5. 正则表达式-----re库

    1.正则表达式的概念 a.为什么要用正则? 用字符串匹配也是可以的: startswith() 方法用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False.如果参数 be ...

  6. vue+element-ui实现表格checkbox单选

    公司平台利用vue+elementui搭建前端页面,因为本人第一次使用vue也遇到了不少坑,因为我要实现的效果如下图所示 实现这种单选框,只能选择一个,但element-ui展示的是多选框,check ...

  7. spider随机请求头和ip

    #创建爬虫 scrapy genspider randomIp_spider "taobao.com" #把需要请求的url放到一个混淆的url请求list中去,避免被监测到总是访 ...

  8. winrar目录穿越漏洞

    地址: 参考: https://research.checkpoint.com/extracting-code-execution-from-winrar/ POC: https://github.c ...

  9. “行业客户云原生最佳实践日” 亮相KubeCon上海

    2018年11月13日至15日,由CNCF主办的KubeCon + CloudNativeCon将首次登陆中国上海,这是全球范围内规模最大的Kubernetes和云原生技术盛会. 唯一聚焦客户实践的分 ...

  10. 记一个神奇的Bug

    多年以后,当Abraham凝视着一行行新时代的代码在屏幕上川流不息的时候,他会想起2019年4月17日那个不平凡夜晚,以及在那个夜晚他发现的那个不可思议的Bug. 虽然像无数个普普通通的夜晚一样,我在 ...