關(guān)于socket.io的使用

原文地址:關(guān)于socket.io的使用

這段時(shí)間學(xué)習(xí)了socket.io,用它寫了小項(xiàng)目舀奶,在此總結(jié)下它的基本使用方式和一些要點(diǎn)。
socket.io是基于Node.jsWebSocket協(xié)議的實(shí)時(shí)通信開源框架碌宴,它包括客戶端的JavaScript和服務(wù)器端的Node.js页慷。

服務(wù)端

這里后端使用的框架是koa2socket.io將自身綁定到koa的進(jìn)程中去执庐,其中最重要的事件就是 connectiondisconnect酪耕。它們是框架本身定義的系統(tǒng)事件,也就意味著它是自然就存在的不需要我們自定義轨淌,當(dāng)然還有其它系統(tǒng)事件迂烁,但很少會用得到看尼。

const koa = require('koa')
const app = new koa()
const server = require('http').createServer(app.callback())
const io = require('socket.io')(server)

//監(jiān)聽connect事件
io.on('connection', socket => {
  socket.emit('open');//通知客戶端已連接
  console.log('connected');
  
  //監(jiān)聽disconnect事件
  socket.on('disconnect', () => {
    console.log('disconnect')
  }
});
server.listen(3001);

客戶端

web端直接傳入url地址即可,其中這里監(jiān)聽的 open 事件是用戶自定義的盟步,對應(yīng)服務(wù)端的則是發(fā)送open事件藏斩。

import io from 'socket.io-client';

//建立websocket連接
const socket = io('http://127.0.0.1:3001');

//收到server的連接確認(rèn)
socket.on('open', () => {
    showTip('socket io is open !');
    init();
});

emit 和 on

emiton 是最重要的兩個(gè)api,分別對應(yīng) 發(fā)送監(jiān)聽 事件却盘。

  • socket.emit(eventName[, ...args]):發(fā)射(觸發(fā))一個(gè)事件
  • socket.on(eventName, callback):監(jiān)聽一個(gè) emit 發(fā)射的事件

我們可以非常自由的在服務(wù)端定義并發(fā)送一個(gè)事件emit狰域,然后在客戶端監(jiān)聽 on,反過來也一樣黄橘。

發(fā)送的內(nèi)容格式也非常自由兆览,既可以是基本數(shù)據(jù)類型 NumberString塞关,Boolean 等拓颓,也可以是 ObjectArray 類型描孟,甚至還可以是函數(shù)驶睦。而用回調(diào)函數(shù)的方式則可以進(jìn)行更便攜的交互。

/*** 服務(wù)端 **/
socket.on('message',data =>{
  console.log(data)
});

socket.emit('send','hello everybody');

/*** 客戶端 **/
socket.emit('message',{id:'1',txt:'hello'});

socket.on('send',data =>{
  console.log(data);
});

//回調(diào)函數(shù)
/*** 服務(wù)端 **/
socket.on('sayit', (word, callback)=> {
  callback('say ' + word);
});

/*** 客戶端 **/
socket.emit('sayit', 'wow', data => { 
  console.log(data); // say wow
});
 

broadcast 廣播

broadcast 默認(rèn)是向所有的socket連接進(jìn)行廣播匿醒,但是不包括發(fā)送者自身场航,如果自己也打算接收消息的話,需要給自己單獨(dú)發(fā)送廉羔。

/*** 服務(wù)端 **/
io.on('connection', socket => {
 const data= {
   txt:'new user login',
   time:new Date()
 }
 //廣播向所有socket連接
 socket.broadcast.emit('userin',data);
 //給自己也發(fā)一份
 socket.emit('userin',data);
});

namespace 命名空間

如果你想隔離作用域溉痢,或者劃分業(yè)務(wù)模塊,namespace 是個(gè)有效的法子憋他。namespace 相當(dāng)于建立新的頻道孩饼,你可以在一個(gè) socket.io 服務(wù)上面隔離不同的連接,事件和中間件竹挡。

默認(rèn)的連接也是有namespace的镀娶,那就是 /
使用命名空間的方式一:直接在鏈接后面加子域名揪罕,這種其實(shí)用的還是同一個(gè) sokcet 服務(wù)進(jìn)程梯码,可以看成是軟隔離吧。

/*** 客戶端 **/
import io from 'socket.io-client';

//默認(rèn)的namespace
const socket = io('http://127.0.0.1:3001');
// mypath
const socket = io('http://127.0.0.1:3001/mypath', { forceNew: true });

/*** 服務(wù)端 **/
//默認(rèn)的namespace
io.on('connection', socket => {
});
// mypath
io.of('/mypath').on('connection', socket => {
});

使用命名空間的方式二: path 參數(shù)好啰,這種就是實(shí)打?qū)嵉闹匦缕鹆艘粋€(gè) socket 服務(wù)了轩娶。

/*** 客戶端 **/
const socket = io('http://localhost', {
  path: '/mypath'
});

/*** 服務(wù)端 **/
// 另外重新起socket服務(wù)
const io = require('socket.io')({
  path: '/mypath'
});

middleware 中間件

socket.io 的中間件 和 kao2 的非常相似,這意味著我們可以在變動很小的情況下框往,將koa2的中間件改造為 socket.io 所用鳄抒。

const mypath = io.of('/mypath').on('connection', socket => {
    socket.on('message', data => {
    });
});

//中間件
const auth = (socket, next) => {
  const data = socket.request;
  if(!verify(data)){
    throw new Error('not verify');
  }
  next();
}
// mypath 這個(gè) namespace 注冊中間件
mypath.use(auth);

rooms

每一個(gè)socket連接都會有一個(gè)獨(dú)一無二的標(biāo)志,那就是 socket.id,我們就是通過id來區(qū)分不同連接的许溅。除此之外瓤鼻,socket.id 本身也是房間 room 的標(biāo)志,通俗講闹司,每個(gè)socket 連接自身都擁有一間房 room。那么我們就可以給這個(gè) room 發(fā)送消息沐飘,還有如果你加入了房間游桩,就能接受到房間里的廣播信息。當(dāng)然你可以自定義 room 耐朴,讓socket連接加入或離開借卧。還有如果 socket 斷開連接,也就是 disconnect 后筛峭,它會被自動移出room铐刘。

而這就是實(shí)現(xiàn) 單獨(dú)聊天群組聊天 的基礎(chǔ),來看一下對應(yīng)的api影晓。

  • socket.join(rooms[, callback]):加入房間
  • socket.leave(room[, callback]) :離開房間
  • socket.to(room): 給房間發(fā)送消息
// 自定義room
io.on('connection', socket =>{    
  socket.join('some room')); // 加入房間
  socket.leave('some room'); // 離開房間
}); 

// 向房間里的所有客戶端發(fā)送消息
io.to('some room').emit('some event'); 

// 默認(rèn)房間(每一個(gè)id一個(gè)room)
socket.on('say to someone', (id, msg) => {    
    socket.broadcast.to(id).emit('my message', msg); 
}); 

總結(jié)

相信有了以上介紹的基礎(chǔ)知識镰吵,再加上官網(wǎng)對應(yīng)的文檔,要開發(fā)聊天室或者其他 實(shí)時(shí)通信 的項(xiàng)目挂签,是一件易如反掌的事情

socket.io官網(wǎng) 里面有對 api 非常詳細(xì)的講解和用例疤祭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市饵婆,隨后出現(xiàn)的幾起案子勺馆,更是在濱河造成了極大的恐慌,老刑警劉巖侨核,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件草穆,死亡現(xiàn)場離奇詭異,居然都是意外死亡搓译,警方通過查閱死者的電腦和手機(jī)悲柱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來些己,“玉大人诗祸,你說我怎么就攤上這事≈嶙埽” “怎么了直颅?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長怀樟。 經(jīng)常有香客問我功偿,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任械荷,我火速辦了婚禮共耍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吨瞎。我一直安慰自己痹兜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布颤诀。 她就那樣靜靜地躺著字旭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪崖叫。 梳的紋絲不亂的頭發(fā)上遗淳,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機(jī)與錄音心傀,去河邊找鬼屈暗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛脂男,可吹牛的內(nèi)容都是我干的养叛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼宰翅,長吁一口氣:“原來是場噩夢啊……” “哼一铅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起堕油,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤潘飘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后掉缺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卜录,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年眶明,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了艰毒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搜囱,死狀恐怖丑瞧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜀肘,我是刑警寧澤绊汹,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站扮宠,受9級特大地震影響西乖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一获雕、第九天 我趴在偏房一處隱蔽的房頂上張望薄腻。 院中可真熱鬧,春花似錦届案、人聲如沸庵楷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尽纽。三九已至,卻和暖如春球碉,著一層夾襖步出監(jiān)牢的瞬間蜓斧,已是汗流浹背仓蛆。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工睁冬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人看疙。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓豆拨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親能庆。 傳聞我的和親對象是個(gè)殘疾皇子施禾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容