如何使用JavaScript与Node.js打造一款聊天App
发表于:2025-02-21 作者:千家信息网编辑
千家信息网最后更新 2025年02月21日,这篇文章将为大家详细讲解有关如何使用JavaScript与Node.js打造一款聊天App,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。聊天是我们人与
千家信息网最后更新 2025年02月21日如何使用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安全错误
数据库的锁怎样保障安全
王者荣耀注销服务器60天
ggv 数据库投资
网络安全法实名制是否强制
公司使用云数据库吗
数据库c盘安装图解
郧阳区专业软件开发市场
大连ibm应用软件开发
湛江汽车软件开发设计
学软件开发需要什么文化
同方知网数据库登录
性能测试工资与软件开发
网络安全审查工作开展情况
c 数据库开发 案例
服务器设为公网地址连接防火墙
南京定制app软件开发
临海管理软件开发
桔子it数据库
从事网络安全工作的知识点
服务器管理仪表盘
数据库增添数据
移动网络技术发展的原因
为服务器进行安全加固英文
5g网络技术标准
数据库三级刷一遍题才能过吗
兰州软件开发公司好吗
ATE用哪个软件开发
十万名用户要多大的服务器
柳州计算机网络技术学校
java数据库开发教程
一台服务器做两个阵列卡