這篇文章給大家分享的是有關(guān)Nodejs如何實(shí)現(xiàn)多房間簡(jiǎn)易聊天室功能的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、微信平臺(tái)小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了孝昌免費(fèi)建站歡迎大家使用!JS是JavaScript的簡(jiǎn)稱,它是一種直譯式的腳本語言,其解釋器被稱為JavaScript引擎,是瀏覽器的一部分,主要用于web的開發(fā),可以給網(wǎng)站添加各種各樣的動(dòng)態(tài)效果,讓網(wǎng)頁更加美觀。
1、前端界面代碼
前端不是重點(diǎn),夠用就行,下面是前端界面,具體代碼可到github下載。
2、服務(wù)器端搭建
本服務(wù)器需要提供兩個(gè)功能:http服務(wù)和websocket服務(wù),由于node的事件驅(qū)動(dòng)機(jī)制,可將兩種服務(wù)搭建在同一個(gè)端口下。
1、包描述文件:package.json,這里用到了兩個(gè)依賴項(xiàng),mime:確定靜態(tài)文件mime類型,socket.io:搭建websocket服務(wù),然后使用npm install 安裝依賴
{ "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服務(wù)器
http服務(wù)主要是給web瀏覽器提供靜態(tài)文件,既瀏覽器發(fā)來一個(gè)請(qǐng)求,服務(wù)器返回一個(gè)響應(yīng)。
const http=require('http'), fs=require('fs'), path=require('path'), mime=require('mime'), chatServer=require('./lib/chat_server'); var cache={};//緩存靜態(tài)文件內(nèi)容 //發(fā)送錯(cuò)誤響應(yīng) function send404(response){ response.writeHead(404,{'Content-Type':'text/plain'}); response.write('Error 4.4:文件未找到。'); response.end(); } //發(fā)送文件內(nèi)容 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,absPath,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,cache,absPath); }); server.listen(3000,function(){ console.log("the server is listening on prot 3000."); }); chatServer.listen(server); //websocket服務(wù)也綁定到該端口上
3、socket服務(wù)
socket.io提供了開箱既用的虛擬通道,所以不需要任務(wù)手動(dòng)轉(zhuǎn)發(fā)消息到已連接的的用戶,可以使用 socket.broadcast.to(room).emit('message','hello'); room為某個(gè)聊天室id
const socketio=require('socket.io'); var io, guestNumber=1, //用戶編號(hào) nickNames={}, //socket id對(duì)應(yīng)的nickname namesUsed={}, //所有已使用的nickname allRooms={}, //聊天室--人數(shù) currentRoom={}; //sockid--聊天室 module.exports.listen=function(server){ io=socketio.listen(server); io.serveClient('log level',1); io.sockets.on('connection',function(socket){ guestNumber=assignGuestName(socket,guestNumber,nickNames); joinRoom(socket,'Lobby'); handleMessageBroadcasting(socket,nickNames); handleNameChangeAttempts(socket,nickNames,namesUsed); handleRoomJoining(socket); socket.on('rooms',function(){ socket.emit('rooms',JSON.stringify(allRooms)); }); handleClientDisconnection(socket,nickNames,namesUsed); }); }; //新socket連入,自動(dòng)分配一個(gè)昵稱 function assignGuestName(socket,guesetNumber,nickNames){ var name='Guest'+guestNumber; nickNames[socket.id]=name; socket.emit('nameResult',{ success:true, name:name }); namesUsed[name]=1; return guestNumber+1; } //加入某個(gè)聊天室 function joinRoom(socket,room){ socket.join(room); var num=allRooms[room]; if(num===undefined){ allRooms[room]=1; }else{ allRooms[room]=num+1; } currentRoom[socket.id]=room; socket.emit('joinResult',{room:room}); socket.broadcast.to(room).emit('message',{ text:nickNames[socket.id]+' has join '+room+'.' }); var usersinRoom=io.sockets.adapter.rooms[room]; if(usersinRoom.length>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,nickNames,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 previousName=nickNames[socket.id]; delete namesUsed[previousName]; namesUsed[name]=1; nickNames[socket.id]=name; 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.' }); } } }); } //將某個(gè)用戶的消息廣播到同聊天室下的其他用戶 function handleMessageBroadcasting(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 }); }); } //加入/創(chuàng)建某個(gè)聊天室 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 handleClientDisconnection(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、客戶端實(shí)現(xiàn)socket.io
1、chat.js處理發(fā)送消息,變更房間,聊天命令。
var Chat=function(socket){ this.socket=socket;//綁定socket } //發(fā)送消息 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 處理用戶輸入,根據(jù)輸入調(diào)用chat.js的不同方法發(fā)送消息給服務(wù)器
function divEscapedContentElement(message){ return $('').text(message); } function divSystemContentElement(message){ return $('').html(''+message+''); } function processUserInput(chatApp,socket){ var message=$('#send-message').val(); var systemMessage; if(message.charAt(0)=='/'){ systemMessage=chatApp.processCommand(message); if(systemMessage){ $('#messages').append(divSystemContentElement(systemMessage)); } }else{ chatApp.sendMessage($('#room').text(),message); $('#messages').append(divSystemContentElement(message)); $('#messages').scrollTop($('#messages').prop('scrollHeight')); } $('#send-message').val(''); }
3、init.js客戶端程序初始化 創(chuàng)建一個(gè)websocket連接,綁定事件。
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 known as '+result.name+'.'; }else{ message=result.message; } console.log("nameResult:---"+message); $('#messages').append(divSystemContentElement(message)); $('#nickName').text(result.name); }); socket.on('joinResult',function(result){ console.log('joinResult:---'+result); $('#room').text(result.room); $('#messages').append(divSystemContentElement('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); }); });
感謝各位的閱讀!關(guān)于“Nodejs如何實(shí)現(xiàn)多房間簡(jiǎn)易聊天室功能”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站www.cdcxhl.com,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。