1、前端界面代码
前端不是重点,够用就行,下面是前端界面,具体代码可到github下载。
2、服务器端搭建
本服务器需要提供两个功能:http服务和websocket服务,由于node的事件驱动机制,可将两种服务搭建在同一个端口下。
1、包描述文件:package.json,这里用到了两个依赖项,mime:确定静态文件mime类型,socket.io:搭建websocket服务,然后使用npm install 安装依赖
rush:js;">
{
"name": "chat_room","version": "1.0.0","description": "this is a room where you can chat with your friends","main": "index.js","scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},"author": "sfs","license": "ISC","dependencies": {
"socket.io":"2.0.3","mime":"1.3.6"
}
}
2、http服务器
http服务主要是给web浏览器提供静态文件,既浏览器发来一个请求,服务器返回一个响应。
rush:js;">
const
http=require('http'),fs=require('fs'),path=require('path'),mime=require('mime'),chatServer=require('./lib/chat_server');
var cache={};//缓存静态文件内容
//发送错误响应
function send404(response){
response.writeHead(404,{'Content-Type':'text/plain'});
response.write('Error 4.4:文件未找到。');
response.end();
}
//发送文件内容
function sendFile(response,filePath,fileContents){
response.writeHead(
200,{"content-Type":mime.lookup(path.basename(filePath))}
);
response.end(fileContents);
}
//查找文件
function serveStatic(response,cache,absPath){
if(cache[absPath]){
sendFile(response,absPath,cache[absPath]);
}else{
fs.exists(absPath,function(exists){
if(exists){
fs.readFile(absPath,function(err,data){
if(err){
send404(response);
}else{
cache[absPath]=data;
sendFile(response,data);
}
});
}else{
send404(response);
}
});
}
}
//入口
var server=http.createServer(function(request,response){
var filePath=false;
console.log(new request for ${request.url}
);
if(request.url==='/'){
filePath='public/index.html';
}else{
filePath='public'+request.url;
}
var absPath='./'+filePath;
serveStatic(response,absPath);
});
server.listen(3000,function(){
console.log("the server is listening on prot 3000.");
});
chatServer.listen(server); //websocket服务也绑定到该端口上
3、socket服务
socket.io提供了开箱既用的虚拟通道,所以不需要任务手动转发消息到已连接的的用户,可以使用 socket.broadcast.to(room).emit('message','hello'); room为某个聊天室id
1){
var usersInRoomSummary='Users currently in '+room+' : ';
for(var index in usersinRoom
.sockets){
if(index!=socket.id){
usersInRoomSummary+=nickNames[index]+',';
}
}
socket.emit('message',{text:usersInRoomSummary});
}
}
//
修改昵称
function handleNameChangeAttempts(socket,namesUsed){
socket.on('nameAttempt',function(name){
if(name.indexOf('Guest')==0){
socket.emit('nameResult',{
success:false,message:'Names cannot begin with "Guest".'
});
}else{
if(namesUsed[name]==undefined){
var prev
IoUsName=nickNames[socket.id];
delete namesUsed[prev
IoUsName];
namesUsed[name]=1;
nickNames[socket.id]=name;
socket.emit('nameResult',{
success:true,name:name
});
socket.
broadcast.to(currentRoom[socket.id]).emit('message',{
text:prev
IoUsName+' is
Now k
Nown as '+name+'.'
});
}else{
socket.emit('nameResult',{
success:false,message:'That name is already in use.'
});
}
}
});
}
//将某个
用户的消息广播到同聊天室下的其他
用户
function handleMessage
broadcasting(socket){
socket.on('message',function(message){
console.log('message:---'+JSON.stringify(message));
socket.
broadcast.to(message.room).emit('message',{
text:nickNames[socket.id]+ ': '+message.text
});
});
}
//加入/创建某个聊天室
function handleRoomJoining(socket){
socket.on('join',function(room){
var temp=currentRoom[socket.id];
delete currentRoom[socket.id];
socket.leave(temp);
var num=--allRooms[temp];
if(num==0)
delete allRooms[temp];
joinRoom(socket,room.newRoom);
});
}
//socket断线处理
function handleClient
disconnection(socket){
socket.on('
disconnect',function(){
console.log("xxxx
disconnect");
allRooms[currentRoom[socket.id]]--;
delete namesUsed[nickNames[socket.id]];
delete nickNames[socket.id];
delete currentRoom[socket.id];
})
}
3、客户端实现socket.io
1、chat.js处理发送消息,变更房间,聊天命令。
rush:js;">
var Chat=function(socket){
this
.socket=socket;//绑定socket
}
//发送消息
Chat.prototype.sendMessage=function(room,text){
var message={
room:room,text:text
};
this
.socket.emit('message',message);
};
//变更房间
Chat.prototype.changeRoom=function(room){
this
.socket.emit('join',{
newRoom:room
});
};
//处理聊天命令
Chat.prototype.processCommand=function(command){
var words=command.split(' ');
var command=words[0].substring(1,words[0].length).toLowerCase();
var message=false;
switch(command){
case 'join':
words.shift();
var room=words.join(' ');
this.changeRoom(room);
break;
case 'nick':
words.shift();
var name=words.join(' ');
this
.socket.emit('nameAttempt',name);
break;
default:
message='Unrecognized command.';
break;
}
return message;
};
2、chat_ui.js 处理用户输入,根据输入调用chat.js的不同方法发送消息给服务器
rush:js;">
function
divescapedContentElement(message){
return $('
').text(message);
}
function divSy
stemContentElement(message){
return $('
').html('
'+message+'');
}
function processUserInput(chatApp,socket){
var message=$('#send-message').val();
var sy
stemMessage;
if(message.ch
arat(0)=='/'){
sy
stemMessage=chatApp.processCommand(message);
if(sy
stemMessage){
$('#messages').append(divSy
stemContentElement(sy
stemMessage));
}
}else{
chatApp.sendMessage($('#room').text(),message);
$('#messages').append(divSy
stemContentElement(message));
$('#messages').scrollTop($('#messages').prop('scrollHeight'));
}
$('#send-message').val('');
}
3、init.js客户端程序初始化 创建一个websocket连接,绑定事件。
rush:js;">
if(window.WebSocket){
console.log('This
browser supports WebSocket');
}else{
console.log('This
browser does not supports WebSocket');
}
var socket=io.connect();
$(document).ready(function(){
var chatApp=new Chat(socket);
socket.on('nameResult',function(result){
var message;
if(result.success){
message='You are k
Nown as '+result.name+'.';
}else{
message=result.message;
}
console.log("nameResult:---"+message);
$('#messages').append(divSy
stemContentElement(message));
$('#nickName').text(result.name);
});
socket.on('joinResult',function(result){
console.log('joinResult:---'+result);
$('#room').text(result.room);
$('#messages').append(divSy
stemContentElement('Room changed.'));
});
socket.on('message',function(message){
console.log('message:---'+message);
var newElement=$('
').text(message.text);
$('#messages').append(newElement);
$('#messages').scrollTop($('#messages').prop('scrollHeight'));
});
socket.on('rooms',function(rooms){
console.log('rooms:---'+rooms);
rooms=JSON.parse(rooms);
$('#room-list').empty();
for(var room in rooms){
$('#room-list').append(
divescapedContentElement(room+':'+rooms[room]));
}
$('#room-list div').click(function(){
chatApp.processCommand('/join '+$(this).text().split(':')[0]);
$('#send-message').focus();
});
});
setInterval(function(){
socket.emit('rooms');
},1000);
$('#send-message').focus();
$('#send-button').click(function(){
processUserInput(chatApp,socket);
});
});
完整代码,可到https://github.com/FleyX/ChatRoom 下载。
以上所述是小编给大家介绍的Nodejs实现多房间简易聊天室功能。编程之家 jb51.cc 收集整理的教程希望能对你有所帮助,如果觉得编程之家不错,可分享给好友!感谢支持。