如何使用JavaScript与Node.js打造一款聊天App
发表于:2025-02-19 作者:千家信息网编辑
千家信息网最后更新 2025年02月19日,这篇文章将为大家详细讲解有关如何使用JavaScript与Node.js打造一款聊天App,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。聊天是我们人与
千家信息网最后更新 2025年02月19日如何使用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安全错误
数据库的锁怎样保障安全
电池与服务器布置要求
成都有什么软件开发公司
德国互联网科技
海纳科技互联网有限公司
徐州工业网络技术信息推荐
区县行政矢量数据库
乱世王者服务器进不去
数据库修改学生专业
二手服务器下架
数据库集群与redis
区委网络安全委员会议
nacos不使用数据库
拆分器无法连接服务器
怀柔区软件开发诚信服务
郑州好的软件开发公司
vc2008数据库
湖州闪银网络技术有限公司
软件开发3 2学校
地质灾害数据库
加强网络安全产值
南京电商软件开发供应商
合肥六度网络技术有限公司
数据库怎么改成自动
天津股权投资管理软件开发
温州通信网络技术应用
创世神奇宝贝服务器手机版
软件开发的后台指的是
网络图是网络技术的什么
梦三国2无法连接服务器
常见高速网络技术