node.js + socket.io 實(shí)現(xiàn)點(diǎn)對點(diǎn)隨機(jī)匹配聊天
真心佩服那些可以經(jīng)常發(fā)布筆記的人,其實(shí)我也想經(jīng)常發(fā)來的,奈何技術(shù)不夠加上懶,要向大神們多多學(xué)習(xí)了,前段時間有用bomb平臺自帶的socket寫一個聊天室,其實(shí)基本就是改了改它的demo,這次想實(shí)現(xiàn)一個隨機(jī)私聊,所以自己基于node 和 socket.io 來搭服務(wù),當(dāng)然,第一次用node做東西玩,雖然做的不好,但是也蠻分享下哈。
先說說用到的東西, node 用來做后臺服務(wù),express 用來托管靜態(tài)資源,然后socket.io 用來傳送聊天數(shù)據(jù)。接下來說說思路,其實(shí)用socket.io來傳數(shù)據(jù)是很簡單的一件事情,我們只需要再前端頁面引入 socket.io.js 然后再node端也require('socket.io'),把它在后端跑起來,那么前端就可以通過如下代碼來發(fā)送或者接收信息。
//前端 socket = io.connect('ws://'+'服務(wù)器ip'); socket.emit('msg',{msg:'前端要發(fā)送的信息'});//要發(fā)送的信息(以對象的形式發(fā)送) socket.on('msg2',function(data){ ... //這里的data是后端傳過來的信息 }) //后端 socket.on('msg',function(data){ var data = data; //這里的data就是前端傳過來的數(shù)據(jù),即{msg:'前端要發(fā)送的信息'} console.log(data.msg) // 打印出 “前端要發(fā)送的信息” }) //同理,后端要傳信息給前端也是一樣 socket.emit('msg2',{msg:'后端要發(fā)送的信息'});
我們來看后端怎么把socket跑起來
var express = require('express'); var app = express(); var http = require('http').Server(app); var io = require('socket.io')(http); io.on('connection', function(socket){ //當(dāng)前端執(zhí)行 socket = io.connect('ws://'+host); 的時候,此處的io會監(jiān)聽到connection事件 socket.on('msg',function(data){ io.emit('onlineCount',freeList) //如果直接用io.emit來發(fā)送數(shù)據(jù)的話,這代表廣播的形式,就是當(dāng)前所有打開服務(wù)的前端頁面都會收到這條消息。 socket.emit('welcome',{msg:'歡迎...'})//這里將給當(dāng)前連接的頁面發(fā)送一個歡迎的對象數(shù)據(jù) }) socket.on('disconnect',function(){ //當(dāng)前端頁面關(guān)閉,或者失去連接時,后端會接收到disconnect事件 }) }) http.listen(4000, function(){ console.log('listening on *:4000'); });
當(dāng)然不僅如此,因?yàn)閣ebsocket協(xié)議,是在瀏覽器和服務(wù)器之間建立了一個長鏈接來相互傳輸數(shù)據(jù),對服務(wù)器而言,如果打開了好幾個頁面,那么就有好幾個socket實(shí)例,每個建立連接的前端頁面都會有一個socket實(shí)例,這樣就為接下來的點(diǎn)對點(diǎn)私聊提供了思路。當(dāng)然,我們也可以通過直接廣播來傳送信息,不過這適用于聊天室情景。
那如何實(shí)現(xiàn)點(diǎn)對點(diǎn)呢,之前說了,每個建立連接的頁面都會產(chǎn)生一個socket實(shí)例,那么我們只需要后端在接收消息的同時,判斷該socket實(shí)例是和哪個個實(shí)例在聊天,只把消息發(fā)送給另一個匹配的socket實(shí)例就好了。簡單來說就像寫信一樣,我把消息發(fā)送給后端,然后告訴后端,這個消息是給xxx的,然后后端找到xxx對應(yīng)的socket實(shí)例,將消息發(fā)給他就好了。
//前端 window.id = new Date().getTime()+""+Math.floor(Math.random()*899+100); //每次登錄,獲取一個唯一的用戶id socket = io.connect('ws://'+host); socket.emit('newUser',{ user_name : name, user_id : id}) //建立連接后,將我的用戶名和id都傳給后端 //后端 socket.on('newUser',function(data){ var nickname = data.user_name, user_id = data.user_id; userServer[user_id] = socket; //后端接收后,將該用戶socket保存在一個對象里,key值為id,value就是這個用戶的socket })
通過上面的代碼,后端得到了一個userServer的對象,里面是每個連接socket和其id的對應(yīng)值,這樣,就可以通過每次發(fā)送信息時,附帶要接收對象的id來達(dá)到點(diǎn)對點(diǎn)的數(shù)據(jù)傳輸。
接下來就是數(shù)據(jù)處理咯,如何取到對方的id啊等等,鑒于我表達(dá)能力有限,加上懶,就不啰嗦啦~~ 代碼我都托管在github歡迎自己下下來看咯~https://github.com/mikoshu/mychatroom.git
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
node.js中fs.stat與fs.fstat的區(qū)別詳解
fs.stat和fs.fstat他們都是用來獲取文件的狀態(tài)信息,下面這篇文章主要給大家介紹了關(guān)于node.js中fs.stat與fs.fstat區(qū)別的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。2017-06-06nodejs+express最簡易的連接數(shù)據(jù)庫的方法
這篇文章主要介紹了nodejs+express 最簡易的連接數(shù)據(jù)庫,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12nodeJS代碼實(shí)現(xiàn)計(jì)算交社保是否合適
本文通過nodejs的一個具體示例來對比分析現(xiàn)階段我們交社保合不合適,主要是對nodejs的一個小的應(yīng)用,當(dāng)然大家也可以改成其他語言的,程序猿們,來算算吧。2015-03-03