如何使用JavaScript与Node.js打造一款聊天App
发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,这篇文章将为大家详细讲解有关如何使用JavaScript与Node.js打造一款聊天App,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。聊天是我们人与
千家信息网最后更新 2024年11月23日如何使用JavaScript与Node.js打造一款聊天App
这篇文章将为大家详细讲解有关如何使用JavaScript与Node.js打造一款聊天App,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
聊天是我们人与人交流最直接的方式,互联网的加入使我们交流更加便捷。我们手机上的微信、QQ是我们手机必不可少的应用软件。那么,我们是否可以做一款聊天应用呢?
之前我自己闲着没事,研究过一些技术,做了一款即时通讯应用,下面我将选取几幅具有代表性的图片供大家参考。
一、应用示图
以上是这款应用的主要页面,功能可能相对简陋点,不过基本的功能已经实现了,下面我将给出核心代码,全部源码地址在文末。
二、部分核心源码
前台主要核心逻辑:
这里我只列举了js核心代码,查看完整代码可以去文末。
function sock() { return io.connect("http://localhost:3003"); // http环境下 } // 心跳机制 document.addEventListener('visibilitychange', function () { if (document.visibilityState == 'hidden') { //记录页面隐藏时间 sock() console.log('隐藏了') } }) setInterval(() => { sock() }, 10000); var socket = sock() var re = document.querySelector("#re"); var register1 = document.querySelector(".register"); var init = document.querySelector(".init"); var passr = document.querySelector("#passr"); var passl = document.querySelector("#passl"); var login1 = document.querySelector(".login"); var register_b = document.querySelector("#register_b"); var lo = document.querySelector("#lo"); var chat = document.querySelector("#chat"); var login_b = document.querySelector("#login_b"); var myMes = ""; var vf = ""; var na = ""; var p = ""; var we = ""; var div = ""; var v = ""; var q = 0; var regCn = /[@:]/im; var pattern = /^[\u4E00-\u9FA5]{1,5}$/; // 同意 document.querySelector('.yes').onclick=function () { document.querySelector('.dark').style.display='none' } document.querySelector('.ys').onclick = function () { document.querySelector('.dark').style.display = 'block' } // 初始页面注册 document.querySelector("#reg").onclick = function () { register1.style.display = "block"; init.style.display = "none"; document.querySelector(".bg").style.display = "none"; } // 初始页面登录 document.querySelector("#log").onclick = function () { login1.style.display = "block"; init.style.display = "none"; document.querySelector(".bg").style.display = "none"; } // 登录按钮 login_b.onclick = function () { login(); } // 注册按钮 register_b.onclick = function () { register(); } //发送 document.getElementById("btn").onclick = function () { send(); }; // 内容填充 document.getElementById("text").onkeyup = function () { if (document.getElementById("text").value.length != 0) { document.getElementById("btn").style.cssText = "background:#98E165;color:#fff;" } else { document.getElementById("btn").style.cssText = "background: #DDDEE2;color:#fff" } } document.querySelector("#text").onclick = function () { document.querySelector('#text').scrollIntoView(false); } // 传名 var users2 = ""; socket.on('users', function (users) { users2 = users; // console.log(users2); }); // 传密码 var pass2 = "" socket.on('pass', function (val) { pass2 = val; // console.log(pass2) }); // 统计在线人数 var arrh = [] socket.on('dataval', function (val) { vf = val; console.log(vf); for (let i = 0; i < vf.length; i++) { // uu++ arrh.push(vf[i]) console.log(arrh) } var rf = [...new Set(arrh)] console.log(rf) rf = vf for (let j = 0; j < rf.length; j++) { var li = document.createElement("li"); li.classList.add("active"); li.innerText = rf[j] console.log(rf[j]) socket.emit("time", rf[j]); document.querySelector(".fix").appendChild(li); } }); socket.on('join', function (val) { document.querySelector(".fix")[xss_clean] = '' }) socket.on('disconnect', function (val) { console.log('离开了') document.querySelector(".fix")[xss_clean] = '' }) // 生成数组 var ar = ""; socket.on('array', function (val) { ar = val; // console.log(ar); }); // 封装注册 function register() { if (re.value.length == 0) { sweetAlert("请输入用户名!"); return false; } else if (regCn.test(re.value)) { sweetAlert("格式错误,不能够用和:符号取名,请重新输入!"); return false; } else if (pattern.test(re.value)) { sweetAlert("不能使用中文字符哦!"); return false; } else if (!(re.value.length == 0 && regCn.test(re.value))) { if (users2.indexOf(re.value) != -1) { sweetAlert("已经注册啦,换一个用户名吧!"); } else { names(re.value.trim()); pass(passr.value.trim()); sweetAlert("注册成功,您的用户名:" + re.value.trim()); document.querySelector(".swal-button").onclick = function () { _window.location.reload(); } } } } //移动端使用touchend var event = navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i) ? 'touchend' : 'click'; // 选择器 var Q = function (id) { return document.getElementById(id) }; //右 var _right = new mSlider({ dom: ".layer-right", direction: "right" }); Q("btnRight").addEventListener(event, function (e) { _right.open(); }) // 封装登录 function login() { if (lo.value.length == 0) { sweetAlert("请输入用户名!"); return false; } else if (regCn.test(lo.value)) { sweetAlert("格式错误,不能够用和:符号取名,请重新输入!"); return false; } else if (pattern.test(lo.value)) { sweetAlert("不能使用中文字符哦!"); return false; } else if (!(lo.value.length == 0 && regCn.test(lo.value))) { if (users2.indexOf(lo.value) != -1) { for (var i = 0; i < users2.length; i++) { if (users2[i] === lo.value && pass2[i] === passl.value) { if (ar.indexOf(lo.value) == -1) { sweetAlert("恭喜您,登录成功!"); socket.emit('setName', lo.value.trim()); names1(lo.value.trim()); login1.style.display = "none"; document.querySelector(".bg").style.display = "none"; document.querySelector(".cd span").style.display = "none"; document.querySelector(".title img").style.display = "block"; document.querySelector(".fix").style.display = "block"; document.querySelector(".title").style.display = "block"; _right.open(); document.querySelector(".swal-button").onclick = function () { document.getElementById("text").focus(); document.querySelector(".fix").addEventListener('click', function (e) { if (e.target.nodeName === "LI" && e.target.innerText != document.title) { _right.close(); document.querySelector(".chat_b").style.display = "block"; document.querySelector(".box").style.display = "block"; document.querySelector(".tit").innerText = e.target.innerText; document.querySelector(".ys").style.display="none"; document.querySelector("#text").focus(); onOff = true; } else { sweetAlert("不能跟自己聊天哦~"); } }) } } else { sweetAlert("不能重复登录哦!"); return } } if (users2[i] === lo.value && pass2[i] != passl.value) { sweetAlert("密码错误!"); return; } } } else { sweetAlert("请先注册哦!"); login1.style.display = "none"; register1.style.display = "block"; } } } // 传名 function names(value) { this.name = value; socket.emit("reg", name); } function names1(value) { this.name1 = value; socket.emit("join", name1); document.title = name1 } // 传密码 function pass(value) { socket.emit("pass", value); } socket.on("join", function (user) { this.na = user; }) socket.on("reg", function (user) { this.na1 = user; }) // 私发消息 socket.on('message1', function (data) { var p1 = document.createElement("div"); var s1 = document.createElement("p"); var s2 = document.createElement("p"); var div1 = document.createElement("div"); var em = document.createElement("em"); var ads = document.createElement("audio"); ads.src = "https://www.maomin.club/data/res.mp3"; ads.className = "ads"; s1.className = "chatlist"; s2.className = "chatlist1"; em.className = "zwasked1"; div1.className = "divbox"; s1.innerText = data.from; s2.innerText = data.msg; s1.appendChild(em); p1.appendChild(s1); p1.appendChild(s2); chat.appendChild(ads); ads.play(); div1.appendChild(p1); chat.appendChild(div1); chat.scrollTop = chat.scrollHeight; }); // 私聊发送 function send() { if (document.getElementById("text").value != "") { socket.emit('sayTo', { from: lo.value, to: document.querySelector(".tit").innerText, msg: document.querySelector("#text").value, }) var p1 = document.createElement("div"); var s1 = document.createElement("p"); var s2 = document.createElement("p"); var em = document.createElement("em"); var div1 = document.createElement("div"); var ads = document.createElement("audio"); p1.style.cssText = "float:right;"; s2.style.cssText = "color:#333;" ads.src = "https://www.maomin.club/data/s.wav"; ads.className = "ads"; div1.className = "divbox"; s1.className = "chatlist"; s1.style.cssText = "color:#333 !important;float:right; !important"; s2.className = "chatlist2"; em.className = "zwasked"; s1.innerText = lo.value; s2.innerText = document.querySelector("#text").value; s1.appendChild(em); p1.appendChild(s1); p1.appendChild(s2); chat.appendChild(ads); ads.play(); div1.appendChild(p1); chat.appendChild(div1); chat.scrollTop = chat.scrollHeight; } else { sweetAlert('请输入内容!'); } chat.scrollTop = chat.scrollHeight; document.querySelector("#text").value = ""; document.querySelector("#text").focus(); }
后台主要核心逻辑:
我这里只列举了http环境的,完整代码中有https环境的。
var http=require("http"); var fs=require("fs"); var express = require('express'); var ws=require("socket.io"); var path=require("path"); var _ = require('underscore'); var usocket = []; var usocket1 = []; var pass=[]; var data=[]; var hashName = {}; var onlineCount = 0; var app = express(); // 静态文件识别 app.use(express.static(path.join(__dirname, './public'))); var server=http.createServer(function (req,res) { var filename = req.url.split('/')[req.url.split('/').length-1]; var suffix = req.url.split('.')[req.url.split('.').length-1]; if(req.url==='/'){ res.writeHead(200, {'Content-Type': 'text/html'}); var html = fs.readFileSync("./public/index.html"); res.end(html) }else if(suffix==='css'){ res.writeHead(200, {'Content-Type': 'text/css'}); res.end(get_file_content(path.join(__dirname, 'public', 'css', filename))); }else if(suffix==='js') { res.writeHead(200, {'Content-Type': 'text/javascript'}); res.end(get_file_content(path.join(__dirname, 'public', 'js', filename))); }else if (suffix in ['gif', 'jpeg', 'jpg', 'png']) { res.writeHead(200, { 'Content-Type': 'image/' + suffix }); res.end(get_file_content(path.join(__dirname, 'public', 'images', filename))); } }); function get_file_content(filepath) { return fs.readFileSync(filepath); } // 获取在线 function broadcast() { io.sockets.emit("dataval", hashName); } //提供私有socket function privateSocket(toId) { return (_.findWhere(io.sockets.sockets, { id: toId })); } // 封装删除 function removeByValue(arr, val) { for (var i = 0; i < arr.length; i++) { if (arr[i] == val) { arr.splice(i, 1); break; } } } // 连接socket var io=ws(server); io.on("connection",function(socket){ // 写入成功后读取测试 fs.readFile('./user.xls', 'utf-8', function (err, data) { if(data!=null){ var value = data.split('\n'); io.sockets.emit("users", value); } }); // 写入成功后读取测试 fs.readFile('./password.xls', 'utf-8', function (err,data) { if(data!=null){ var pass1=data.split('\n'); io.sockets.emit("pass", pass1); } }); broadcast(); // 生成名字 socket.on('setName', function (data) { var name = data; hashName[name] = socket.id; // console.log(hashName[name]); broadcast(); }); // 私聊发送 socket.on('sayTo', function (data) { var toName = data.to; var toId; console.log(toName); if (toId = hashName[toName]) { privateSocket(toId).emit('message1', data); } }); // 离开 socket.on('disconnect', function (name) { name=this.i2; io.emit("disconnect", name); removeByValue(data, name); io.sockets.emit("dataval", data); }) // 在线 socket.on('time', function (val) { // console.log(val); }) // 注册 socket.on("reg", function (name) { usocket[name] = socket; this.i1=name; io.emit("reg", name); var myname =this.i1+"\n"; fs.writeFile('./user.xls', myname, { 'flag': 'a' }, function (err) { if (err) { throw err; } // 写入成功后读取测试 fs.readFile('./user.xls', 'utf-8', function (err,data) { if (err) { throw err; } }); }); }) // 加入 io.emit('connected', ++onlineCount); // console.log(data); io.sockets.emit("array", data); socket.on("join", function (name) { usocket1[name] = socket; this.i2 = name; io.emit("join", name); data.push(name); io.sockets.emit("dataval", data); }) // 密码 socket.on("pass",function(val){ pass[val]=socket; this.i2=val; io.emit("pass", val); var password=this.i2+"\n"; fs.writeFile('./password.xls', password, { 'flag': 'a' }, function (err) { if (err) { throw err; } }); }) }); server.listen(3003); console.log("服务器运行中");
三、源码地址
这个项目是之前写的,欢迎大家进行指正。大家可以复制下面的源码地址,拉取下来就可以在本地实现一个聊天服务。如果你有服务器可以把它部署在服务器上,这样你就可以有一个属于自己的聊天App了。大家可以根据源码进行学习,有不明白的可以随时问我。
https://github.com/maomincoding/chat3
关于如何使用JavaScript与Node.js打造一款聊天App就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
成功
源码
应用
登录
输入
代码
内容
密码
核心
用户
用户名
页面
服务
地址
服务器
环境
错误
在线
封装
测试
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
自动的内网网络安全防护
共享汽车软件开发进度表
企业直销软件开发多少钱
网络安全员证书难不难
网络安全方法dos命令
泗阳大型网络技术大概费用
服务器12v电源接电瓶
辽宁省高新技术产业数据库
有什么软件能打开数据库
SQL数据库专用端口
学生宿舍管理系统数据库源码
linux软件开发个人技能
网络安全怎么自我保护
湖南电信itv服务器云主机
网易用的什么数据库
现代战舰服务器下载
大数据库建设专业就业前景
数据库学分的check约束
工作站与服务器的区别
徐州现代软件开发注意事项
网络安全教程化妆棉
intel 服务器cpu 天梯
手机邮箱添加无法连接服务器
java 服务器写文件
网络安全指标
SQL数据库专用端口
未来几年如何打造一个服务器
柔性软件开发平台
在服务器上建一个excel
徐州现代软件开发注意事项