构建有多个房间的聊天室
版本信息
C:\Users\Administrator>node -v
v18.12.1
C:\Users\Administrator>npm -v
8.19.3
聊天室页面展示
首页
修改昵称
输入 /nick chengdu
切换房间
点击右侧房间列表切换
基础知识文档
nodejs web
使用node 启动一个 web服务
const http = require('http')
const hostname = '127.0.0.1'
const port = 3000
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('Hello World\n')
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${
hostname}:${
port}/`)
})
socket 文档地址
主要代码
server.js
var http = require('http');
var fs = require('fs');
var path = require('path');
var mime = require('mime');
var cache = {
};
const hostname = '127.0.0.1';
const port = 3000;
/**
* 请求不存在时,发送404错误
* @param {*} response
*/
function send404(response) {
response.writeHead(404, {
'Content-Type': 'text/plain'});
response.write('Error 404: resource not found.');
response.end();
}
/**
* 发送文件
* @param {*} response
* @param {*} filePath
* @param {*} fileContents
*/
function sendFile(response, filePath, fileContents) {
response.writeHead(200,
{
"Content-type": mime.lookup(path.basename(filePath))}
);
response.end(fileContents);
}
/**
* 静态资源查找
* @param {*} response
* @param {*} cache
* @param {*} absPath
*/
function serverStatic(response, cache, absPath) {
if (cache[absPath]) {
sendFile(response, absPath, cache[absPath]);
} else {
if (fs.existsSync(absPath)) {
fs.readFile(absPath, function(err, data) {
if (err) {
send404(response);
} else {
cache[absPath] = data;
sendFile(response, absPath, data);
}
});
} else {
send404(response);
}
}
}
var server = http.createServer(function(request, response) {
var filePath = false;
if (request.url == '/') {
filePath = 'public/index.html';
} else {
filePath = 'public' + request.url;
}
var absPath = './' + filePath;
serverStatic(response, cache, absPath);
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${
hostname}:${
port}/`)
});
var chatServer = require('./lib/chat_server');//加载自定义模块
chatServer.listen(server);
chat_server.js
var socketio = require('socket.io');
var io;
var guestNumber = 1;
var nickNames = {
};
var namesUsed = [];
var currentRoom = {
};
var roomNames = new Set();
exports.listen = function(server) {
io = socketio.listen(server);
// 设置日志输出级别 0-error 1-warn 2-info 3-debug, 默认为3
io.set('log level', 2);
io.sockets.on('connection', function(socket) {
guestNumber = assignGuestName(socket, guestNumber);
roomNames.add('Lobby');
joinRoom(socket, 'Lobby'); //用户连接上时把他放入聊天室Lobby
//处理用户的消息, 更名以及聊天室的创建与变更
handleMessageBroadcasting(socket);
handleNameChangeAttempts(socket);
handleRoomJoining(socket);
//用户发出请求时, 展示所有聊天室列表
socket.on('roomlist', function () {
socket.emit('roomlist', {
text: Array.from(roomNames)});
});
//定义用户断开连接后的清除逻辑
handleClientDisconnection(socket);
});
}
function assignGuestName(socket, guestNumber) {
var name = 'Guest' + guestNumber;
nickNames[socket.id] = name;
socket.emit('nameResult', {
success: true,
name: name
});
namesUsed.push(name);
return guestNumber + 1;
}
function joinRoom(socket, room) {
socket.join(room);
currentRoom[socket.id] = room;
socket.emit('joinResult', {
room: room});
socket.broadcast.to(room).emit('message', {
text: nickNames[socket.id] + ' has joined ' + room + ' - '
});
var usersInRoom = io.sockets.clients(room);
if (usersInRoom.length > 1) {
var usersInRoomSummary = 'Users currently in ' + room + ': ';
for (var index in usersInRoom) {
var usersSocketId = usersInRoom[index].id;
if (usersSocketId != socket.id) {
if (index > 0) {
usersInRoomSummary += ', ';
}
usersInRoomSummary += nickNames[usersSocketId];
}
}
usersInRoomSummary += '.';
socket.emit('message', {
text: usersInRoomSummary});
}
}
function handleNameChangeAttempts(socket) {
socket.on('nameAttempt', function(name) {
if (name.indexOf('Guest') == 0) {
socket.emit('nameResult', {
success: false,
message: 'Names cannot begin with "Guest".'
});
} else {
if (namesUsed.indexOf(name) == -1) {
var previousName = nickNames[socket.id];
var previousNameIndex = namesUsed.indexOf(previousName);
namesUsed.push(name);
nickNames[socket.id] = name;
delete namesUsed[previousNameIndex];
socket.emit('nameResult', {
success: true,
name: name
});
socket.broadcast.to(currentRoom[socket.id]).emit('message', {
text: previousName + ' is now known as ' + name + ' . '
});
} else {
socket.emit('nameResult', {
success: false,
message: 'That name is already in use. '
});
}
}
});
}
function handleMessageBroadcasting(socket) {
socket.on('message', function(message) {
socket.broadcast.to(message.room).emit('message', {
text: nickNames[socket.id] + ': ' + message.text
});
});
}
function handleRoomJoining(socket) {
socket.on('join', function(room) {
socket.leave(currentRoom[socket.id]);
roomNames.add(room.newRoom);
joinRoom(socket, room.newRoom);
});
}
function handleClientDisconnection(socket) {
socket.on('disconnect', function() {
var nameIndex = namesUsed.indexOf(nickNames[socket.id]);
delete namesUsed[nameIndex];
delete nickNames[socket.id];
});
}
源码地址
https://gitee.com/3281328128/chat-room.git
下载之后,执行以下命令启动
npm install
node server.js