废话不多说进入正题,登陆这块交互,当用户访问服务器并且成功登陆算一个在线登陆人数,每登陆一个用户,服务器都会把用户信息存入一个数组中,保存在服务器,这里要注意一点,服务器会对用户登陆的用户名进行校验,校验结果会返回给客户端,客户端通过校验结果,改变当前页面是否进入聊天页面。
上面的服务器和客户端交互都是通过socket.io来实现通讯的,前端的业务交互我们这里就采用jquery来实现,在public文件夹下新建js文件夹,下载jquery-3.2.1.min.js、新建main.js。然后对chat.html引入需要的sdk:
<script src="js/jquery-3.2.1.min.js"></script> <script src="js/main.js"></script> //socket.io官网要求这么引入 <script src="/socket.io/socket.io.js"></script>
引入完sdk,我们对main的js添加登录功能:
//main.js
/**
* Created by ddvdd on 2018-02-08.
*/
$(function(){
const url = 'http://127.0.0.1:3000';
let _username = '';
let _$inputname = $('#name');
let _$loginButton = $('#loginbutton');
let socket = io.connect(url);
//设置用户名,当用户登录的时候触发
let setUsername = () => {
_username = _$inputname.val().trim(); //得到输入框中用户输入的用户名
//判断用户名是否存在
if(_username) {
socket.emit('login',{username: _username}); //如果用户名存在,就代表可以登录了,我们就触发登录事件,就相当于告诉服务器我们要登录了
}
else{
alert('请输入用户名!');
}
};
/*前端事件*/
_$loginButton.on('click',function (event) { //监听按钮的点击事件,如果点击,就说明用户要登录,就执行setUsername函数
setUsername();
});
/*socket.io部分逻辑*/
socket.on('loginResult',(data)=>{
/**
* 如果服务器返回的用户名和刚刚发送的相同的话,就登录
* 否则说明有地方出问题了,拒绝登录
*/
if(data.code === 0) {
// 登陆成功,切换至聊天室页面
}
else if(data.code ===1){
alert('用户已登录!');
}
else{
alert('登录失败!');
}
})
});
//app.js
/**
* Created by ddvdd on 2018-02-07.
*/
const express = require('express');
const app = express(); // 创建express实例,赋值给app。
const server = require('http').Server(app);
const io = require('socket.io')(server); //将socket的监听加到app设置的模块里。这两句理解不了的可以去socket.io官网去看
const path = require('path'); // 这是node的路径处理模块,可以格式化路径
const users = []; //用来保存所有的用户信息
let usersNum = 0; //统计在线登录人数
server.listen(3000,()=>{
console.log("server running at 127.0.0.1:3000"); // 代表监听3000端口,然后执行回调函数在控制台输出。
});
/**
* app.get(): express中的一个中间件,用于匹配get请求,说的简单点就是node处理请求的路由,对于不同url请求,让对应的不同app.get()去处理
* '/': 它匹配get请求的根路由 '/'也就是 127.0.0.1:3000/就匹配到它了
* req带表浏览器的请求对象,res代表服务器的返回对象
*/
app.get('/',(req,res)=>{
res.redirect('/static/chat.html'); // express的重定向函数。如果浏览器请求了根路由'/',浏览器就给他重定向到 '127.0.0.1:3000/chat.html'路由中
});
/**
* __dirname表示当前文件所在的绝对路径,所以我们使用path.join将app.js的绝对路径和public加起来就得到了public的绝对路径。
* 用path.join是为了避免出现 ././public 这种奇怪的路径
* express.static就帮我们托管了public文件夹中的静态资源。
* 只要有 127.0.0.1:3000/XXX/AAA 的路径都会去public文件夹下找XXX文件夹下的AAA文件然后发送给浏览器。
*/
app.use('/static',express.static(path.join(__dirname,'./public'))); //一句话就搞定。
/*socket*/
io.on('connection',(socket)=>{ //监听客户端的连接事件
socket.on('login',(data)=>{
if(checkUserName(data)){
socket.emit('loginResult',{code:1}); //code=1 用户已登录
}
else{
//将该用户的信息存进数组中
users.push({
username: data.username,
message: []
});
socket.emit('loginResult',{code:0}); //code=0 用户登录成功
usersNum = users.length;
console.log(`用户${data.username}登录成功,进入ddvdd聊天室,当前在线登录人数:${usersNum}`);
}
});
//断开连接后做的事情
socket.on('disconnect',()=>{ //注意,该事件不需要自定义触发器,系统会自动调用
usersNum = users.length;
console.log(`当前在线登录人数:${usersNum}`);
});
});
//校验用户是否已经登录
const checkUserName = (data) => {
let isExist = false;
users.map((user) => {
if(user.username === data.username){
isExist = true;
}
});
return isExist;
}
内容版权声明:除非注明,否则皆为本站原创文章。
