效果圖


老樣子,還是先放個(gè)效果圖,動(dòng)態(tài)圖,有點(diǎn)大(4M)請(qǐng)耐心等加載。








隨便說說


最近在做東西的時(shí)候有一個(gè)對(duì)戰(zhàn)功能,需要用到Socket技術(shù),于是了解了一番相關(guān)的實(shí)現(xiàn)方案,最后選擇了Node" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運(yùn)營 > 從0開始用Nodejs做一個(gè)聊天室

從0開始用Nodejs做一個(gè)聊天室

時(shí)間:2023-07-22 10:51:01 | 來源:網(wǎng)站運(yùn)營

時(shí)間:2023-07-22 10:51:01 來源:網(wǎng)站運(yùn)營

從0開始用Nodejs做一個(gè)聊天室:

效果圖




老樣子,還是先放個(gè)效果圖,動(dòng)態(tài)圖,有點(diǎn)大(4M)請(qǐng)耐心等加載。








隨便說說




最近在做東西的時(shí)候有一個(gè)對(duì)戰(zhàn)功能,需要用到Socket技術(shù),于是了解了一番相關(guān)的實(shí)現(xiàn)方案,最后選擇了Nodejs以及基于Node的http://socket.io 最主要的原因還是Node比較好寫,相比于PHP好多個(gè)函數(shù)來說簡潔太多了。

本文雖說是從0開始,但不是說無編程基礎(chǔ)的也可以,至少要懂以下東西。
1. 基礎(chǔ)的HTML
2. Javascript語法,很基礎(chǔ)的jQuery語法

因?yàn)楸疚氖钦f從0開始,所以必須要說一下Socket是什么東西,有較好基礎(chǔ)的可以跳過這段直接到 如何開始 處開始。




為什么要使用Socket




不引官話,我直接按照我的理解通俗來說。通常的網(wǎng)站或是其他的聯(lián)網(wǎng)的應(yīng)用,因?yàn)橐@取數(shù)據(jù),都需要發(fā)送一個(gè)請(qǐng)求,這個(gè)請(qǐng)求你可以將它看作一個(gè)網(wǎng)址,比如你在瀏覽器鍵入網(wǎng)址"http://www.baidu.com"回車,就是請(qǐng)求了這個(gè)地址,然后它會(huì)返回給你一些東西,前面的就會(huì)給你返回百度首頁的頁面,瀏覽器自己會(huì)解析它(這又涉及到了其他的方面,我們暫且不談)。

所以通常的用戶和服務(wù)器的通信就只能是:用戶發(fā)送請(qǐng)求 -> 服務(wù)器接受請(qǐng)求 -> 服務(wù)器返回結(jié)果 -> 用戶收到結(jié)果。在這種情況下,想要做即時(shí)應(yīng)用就無法實(shí)現(xiàn)。

想想一下,現(xiàn)在你和別人在對(duì)戰(zhàn),你打掉了他8點(diǎn)血,你可以告訴服務(wù)器這個(gè)信息,但是服務(wù)器沒有辦法在你告訴它之后,也迅速告訴你的對(duì)手,他掉了8點(diǎn)血。除非對(duì)手當(dāng)時(shí)發(fā)送一個(gè)請(qǐng)求,來查看自己當(dāng)前血量。但是游戲是實(shí)時(shí)的,不可能你每隔幾秒鐘就詢問服務(wù)器更新一下自己的血量。

這里的需求就是讓己方的數(shù)據(jù)發(fā)送之后即時(shí)發(fā)送給對(duì)方,那么只需要服務(wù)器也能夠以主動(dòng)發(fā)送數(shù)據(jù)給用戶即可,所以需要一種客戶端<=>服務(wù)器雙向通信的技術(shù),就是Socket。




BTW




本文也相當(dāng)于是Socket.io官方Demo的翻譯,想看原教程的可以去看看原文。








如何開始




那我們知道了為什么要用Socket之后,我們來盤算一下該如何完成這個(gè)項(xiàng)目。

首先我們要用Nodejs,那就要去安裝Nodejs,網(wǎng)上教程很多,我不想贅述,給你們一篇我覺得適合的教程:Nodejs環(huán)境搭建

裝好之后在cmd中鍵入 node -vnpm -v,顯示版本號(hào)就說明安裝沒有問題了。

然后我們先新建一個(gè)工程文件夾,名字就叫node-chat,在里面我們新建兩個(gè)文件,一個(gè)是server.js,一個(gè)是index.html,注意后綴名。







然后先安裝兩個(gè)東西。

打開CMD

因?yàn)閚pm是國外的庫可能有點(diǎn)慢,可以安裝cnpm,執(zhí)行下面命令

npm install -g cnpm --registry=https://registry.npm.taobao.org

然后輸入

cnpm install --save express

等待安裝成功,再安裝

cnpm install --save socket.io

都安裝成功之后我們就可以開始著手Coding了。




功能分析




我們要做一個(gè)聊天室,簡單起見,就不做私聊的功能了,那么我們想要的功能可以是這些:







  1. 每個(gè)人有自己的昵稱,在進(jìn)入聊天室的時(shí)候自己輸入。



  1. 每個(gè)人都可以發(fā)言



  1. 有一個(gè)區(qū)域用來展示所有的發(fā)言,并且要實(shí)時(shí)更新



  1. 有人加入的時(shí)候提示xxx加入了群聊






開始Coding




Nodejs之 Hello World




Nodejs是用來當(dāng)服務(wù)器的,所以我們先來用Nodejs搭建一個(gè)服務(wù)器。其中用到了express這個(gè)框架,不知道的想知道可以搜搜相關(guān)知識(shí),不想知道直接不要管也沒關(guān)系。

讓我們?cè)趕erver.js中寫下以下代碼:




var app = require('express')(); //引入express庫var http = require('http').Server(app); //將express注冊(cè)到http中//當(dāng)訪問根目錄時(shí),返回Hello Worldapp.get('/', function(req, res){ res.send('<h1>Hello world</h1>');});//啟動(dòng)監(jiān)聽,監(jiān)聽3000端口http.listen(3000, function(){ console.log('listening on *:3000');});





保存之后,我們?cè)诿钚衏d到server.js所在的文件夾下,執(zhí)行

node server.js

跟下面圖片相同就說明成功了







然后打開瀏覽器,輸入localhost:3000回車。







OK,Node搭建的服務(wù)器就OK了。接下來,我們讓瀏覽器進(jìn)入的時(shí)候,跳轉(zhuǎn)到我們的index.html頁面,我們?cè)谀菍懥奶焓业慕缑妗?br>



跳轉(zhuǎn)到聊天室頁面




聊天室頁面的實(shí)現(xiàn)




index.html中輸入以下代碼:




<!doctype html><html> <head> <title>Socket.IO chat</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; } </style> </head> <body> <ul id="messages"></ul> <form action=""> <input id="m" autocomplete="off" /><button>發(fā)送</button> </form> </body></html>





保存。




根目錄跳轉(zhuǎn)




前面我們?cè)?code>server.js中寫了根目錄返回hello world,現(xiàn)在我們讓它跳轉(zhuǎn)到聊天室頁面。將server.js中的




app.get('/', function(req, res){ res.send('<h1>Hello world</h1>');});





替換為




app.get('/', function(req, res){ res.sendFile(__dirname + '/index.html');});





然后在CMD中ctrl+c結(jié)束,重新運(yùn)行node server.js。
現(xiàn)在在瀏覽器中訪問localhost:3000,已經(jīng)跳轉(zhuǎn)到聊天頁面了。










引入Socket




繼續(xù)修改server.js,增加下方標(biāo)注內(nèi)容:




var app = require('express')();var http = require('http').Server(app);//new additionvar io = require('socket.io')(http);//endapp.get('/', function(req, res){ res.sendFile(__dirname + '/index.html');});//new additionio.on('connection', function(socket){ console.log('a user connected');});//endhttp.listen(3000, function(){ console.log('listening on *:3000');});





新加入的內(nèi)容的意思就是,當(dāng)有新的socket連接成功之后,就打印一下信息。

然后編輯index.html,添加下方標(biāo)注內(nèi)容:




<!doctype html><html> <head> <title>Socket.IO chat</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; } </style> //new addition <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> //end </head> <body> <ul id="messages"></ul> <form action=""> <input id="m" autocomplete="off" /><button>發(fā)送</button> </form> </body> //new addition <script src="/socket.io/socket.io.js"></script> <script> var socket = io() </script> //end</html>





在上面的內(nèi)容中,引入了jQuery與http://socket.io,并且在頁面加載完成之后,新建了一個(gè)io對(duì)象。

然后我們重新啟動(dòng)node服務(wù),訪問localhost:3000。就會(huì)有以下結(jié)果。










添加交互




當(dāng)用戶有動(dòng)作的時(shí)候,我們要顯示在聊天面板中,就插入一個(gè)li標(biāo)簽好了。在index.html的script中寫一個(gè)方法,后面顯示什么內(nèi)容,就調(diào)用這個(gè)方法在面模板中插入一條li就好了。

將以下代碼寫到index.html中。




function addLine(msg) { $('#messages').append($('<li>').text(msg));}





等等,我們好像忘了什么事情




在前面功能分析的時(shí)候,我們就說用戶剛進(jìn)來的時(shí)候,需要輸入自己的昵稱。
我們現(xiàn)在就先把這個(gè)功能實(shí)現(xiàn)一下。

index.html的script最前面,我們先彈出一個(gè)prompt()來詢問用戶的昵稱,然后將用戶名發(fā)送給后端,讓后端告訴大家這個(gè)用戶進(jìn)來了接。




發(fā)送昵稱給后端




新用戶發(fā)送自己的昵稱給服務(wù)器后,要讓所有處在聊天室的人知道,所以服務(wù)器要發(fā)一個(gè)廣播。發(fā)送數(shù)據(jù)給后端,調(diào)用socket的emit方法,這里指定一個(gè)事件名字叫join,然后后端會(huì)處理這個(gè)事件。

然后現(xiàn)在我們的script標(biāo)簽中是這樣的。




<script> var name = prompt("請(qǐng)輸入你的昵稱:"); var socket = io() //發(fā)送昵稱給后端 socket.emit("join", name) function addLine(msg) { $('#messages').append($('<li>').text(msg)); }</script>





后端發(fā)送廣播




為了在后端區(qū)分用戶,我們用一個(gè)usocket數(shù)組來保存每一個(gè)用戶的socket實(shí)例。

首先監(jiān)聽join事件,在接收到昵稱之后,將該用戶的加入聊廣播給所有用戶。
server.js代碼如下:




為了限制篇幅長度,從此處開始貼上來的代碼有省略,請(qǐng)參考上下文確定位置。



var usocket = []; //全局變量...io.on('connection', function(socket){ console.log('a user connected') //監(jiān)聽join事件 socket.on("join", function (name) { usocket[name] = socket io.emit("join", name) //服務(wù)器通過廣播將新用戶發(fā)送給全體群聊成員 })});...





然后在index.html的script中添加以下代碼,接受到新用戶加入事件的處理:




...//發(fā)送昵稱給后端socket.emit("join", name)//收到服務(wù)器發(fā)來的join事件時(shí)socket.on("join", function (user) { addLine(user + " 加入了群聊")})...





現(xiàn)在我們?cè)賮頊y(cè)試一下,node server.js開啟后端服務(wù),然后訪問localhost:3000,輸入用戶名iimT







然后可以看到







然后新開一個(gè)標(biāo)簽頁,輸入用戶名iimY







在iimY的面板中,可以看到







再回到iimT的面板中,看到新提示的iimY加入了群聊










臨時(shí)加個(gè)小功能




為了更好的辨識(shí)每個(gè)面板是誰,我們?cè)谟脩糨斎胱约旱年欠Q之后,將網(wǎng)頁標(biāo)題改成XXX的聊天。

只需要新加一行代碼:




...//發(fā)送昵稱給后端,并更改網(wǎng)頁titlesocket.emit("join", name)document.title = name + "的群聊" //new addition...





處理發(fā)送和接受消息




【一】index.html 將用戶消息發(fā)送給服務(wù)器




用戶輸入消息,然后點(diǎn)擊發(fā)送我們將用戶的消息發(fā)送給服務(wù)器,然后服務(wù)器將消息廣播給所有的用戶。

我們需要給form的提交綁定一個(gè)事件,讓它來處理新消息的發(fā)送。




$('form').submit(function () { //solve code})





在綁定的事件中,我們需要逐步做以下事情:







  1. 獲取用戶輸入的消息。






var msg = $("#m").val()








  1. 發(fā)送事件給服務(wù)器,事件名就叫message吧,發(fā)送的數(shù)據(jù)就是msg。






socket.emit("message", msg) //將消息發(fā)送給服務(wù)器








  1. 將消息輸入框置空。






$("#m").val("") //置空消息框








  1. 阻止form的提交事件。






return false //阻止form提交





最后,我們給form綁定的事件如下:




...//當(dāng)發(fā)送按鈕被點(diǎn)擊時(shí)$('form').submit(function () { var msg = $("#m").val() //獲取用戶恮的信息 socket.emit("message", msg) //將消息發(fā)送給服務(wù)器 $("#m").val("") //置空消息框 return false //阻止form提交})...





【二】server.js 服務(wù)器接受消息




只需要兩步:
1. 監(jiān)聽前端的message事件
2. 在監(jiān)聽到事件之后,將新消息廣播給全體用戶,這里也將廣播事件的名字叫message吧。

代碼如下:




io.on('connection', function(socket){ console.log('a user connected') socket.on("join", function (name) { usocket[name] = socket io.emit("join", name) }) //new addition socket.on("message", function (msg) { io.emit("message", msg) //將新消息廣播出去 })});





【三】index.html 客戶接受新消息




客戶接收到服務(wù)器發(fā)來的message事件,將新消息呈現(xiàn)在面板中。




...socket.on("join", function (user) { addLine(user + " 加入了群聊")})//接收到服務(wù)器發(fā)來的message事件socket.on("message", function(msg) { addLine(msg)})//當(dāng)發(fā)送按鈕被點(diǎn)擊時(shí)$('form').submit(function () { var msg = $("#m").val() //獲取用戶輸入的信息...





整個(gè)過程相當(dāng)于,用戶a將自己的消息用message事件發(fā)送給服務(wù)器,服務(wù)器監(jiān)聽message事件接收其中的消息,將消息用事件message廣播給全體用戶,全體用戶監(jiān)聽message事件,將事件接受到的消息呈現(xiàn)在聊天框中。PS:這一段是整個(gè)socket編程的核心,可以多讀幾遍細(xì)細(xì)理解。



最終測(cè)試




那么現(xiàn)在我們就完成了整個(gè)聊天室的功能,來測(cè)試一下吧。




1. 開啟服務(wù)器node server.js。













2. 開一個(gè)標(biāo)簽,輸入地址localhost:3000,回車,填寫昵稱為iimT













3. 再開一個(gè)標(biāo)簽,輸入地址localhost:3000,回車,填寫昵稱為iimY。










然后開始讓兩個(gè)人互相發(fā)送消息吧。我這里用一張動(dòng)態(tài)圖來顯示最終效果,也就是本文最開頭的那張效果圖。

PS: 圖大概有4M,所以需要點(diǎn)時(shí)間加載





至此,聊天室以就做完了。




最后




源代碼地址:tfh93121/node-chat




我是iimT, 一個(gè)固執(zhí)的技術(shù)直男。

我的微博 : @_iimT

我的微信公眾號(hào) : iimT

個(gè)人博客:


關(guān)鍵詞:

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉