用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. 去除桌面SVN问号

    由于误操作,桌面文件全部带着问号. 找到一种比较方便的方法解决. 1.显示受保护文件.文件夹win7系统 - 随便打开一个文件夹 -  在菜单栏里点 工具 - 文件夹选项 - 查看 以下如图中选择 2 ...

  2. go/wiki/MutexOrChannel Golang并发:选channel还是选锁?

    https://mp.weixin.qq.com/s/JcED2qgJEj8LaBckVZBhDA https://github.com/golang/go/wiki/MutexOrChannel M ...

  3. Win64/Linux 上PyMouse安装

    目录 windows64安装Pymouse Linux安装 PyMouse ubuntu PyMouse用法 windows64安装Pymouse 只安装PyMouse,会提示缺少相应的组键. 找到安 ...

  4. 2017年年度总结 & 2018年计划

    2017年年度总结 & 2018年计划 2017关键词 「入门」   从2017年4月,入坑软件测试行业,感谢这10个月,给予我开发.测试帮助的前辈们.   这10个月以来, 1,前后花了一个 ...

  5. linux驱动调试记录

    linux驱动调试 linux 目录 /proc 下面可以配置驱动的调试信息,比如给proc目录的自己定制的驱动的一文件设置一个变量,然后驱动程序跟了proc的参数值来配置调试级别.类似于内核调试的级 ...

  6. spring-boot war包

    接着上面的spring-boot项目,直接使用jar包方便调试,在开发阶段非常方便,生产上最好打成war形式 要想spring-boot打war包,还是从pom.xml入手 1.1 调整pom.xml ...

  7. ADB——修改手机默认参数

    修改原理 修改设置的原理主要是通过 settings 命令修改 /data/data/com.android.providers.settings/databases/settings.db 里存放的 ...

  8. 一次完整的http请求过程

    转载:https://blog.51cto.com/linux5588/1351007 当我们在浏览器的地址栏输入 www.linux178.com,然后回车,回车这一瞬间到看到页面到底发生了什么呢? ...

  9. Python request 在linux上持续并发发送HTTP请求遇到 Failed to establish a new connection: [Errno 11] Resource temporarily unavailable

    并发数被限制 vim /etc/sysctl.conf 添加 net.ipv4.ip_local_port_range = 1024 65535   保存 /sbin/sysctl -p 让修改生效 ...

  10. python类与对象-如何为创建大量实例节省内存

    如何为创建大量实例节省内存 问题举例 在网络游戏中,定义玩家类Player(id, name, level...), 每个玩家在线将创建一个Player实例,当在线人数很多时,将产生大量实例, 如何降 ...