傳統的客戶端和服務器通訊協議是HTTP:客戶端發起請求,服務端進行響應,服務端從不主動勾搭客戶端。web
這種模式有個明顯軟肋,就是同步狀態。而實際應用中有大量須要客戶端和服務器實時同步狀態的場景,好比聊天室、股票行情、在線共享文檔等都須要客戶端實時拿到服務器的最新狀態。express
針對這種實時同步的需求,一種簡單的方式是輪詢,好比每隔5s發一次http請求去拿服務器最新的狀態數據。但這種方式會存在數據延遲,浪費帶寬等反作用。npm
更完美的方式是使用WebSocket,瀏覽器原生支持,W3C標準協議,客戶端和服務器創建持久性鏈接能夠互發消息。api
socket.io 是一個類庫,內部封裝了WebSocket,能夠在瀏覽器與服務器之間創建實時通訊。瀏覽器
若是某些舊版本的瀏覽器不支持WebSocket,socket.io會使用輪詢代替。另外它還具備可發送二進制消息、多路複用、建立房間等特性,所以相比直接使用原生WebSocket,socket.io是更好的選擇。服務器
開發一個實時應用主要分兩部分:服務端和客戶端,socket.io分別提供了相應的npm包供咱們方便地調用。websocket
接下來就經過一個生動形象且有趣的栗子分別介紹這兩大塊。網絡
如今假設李白,瑤,呂布,后羿,貂蟬5我的加入了一個叫 KPL 的房間,在文章結束時咱們將擁有一個麻雀雖小五臟俱全的峽谷英雄在線聊天室app
首先安裝socket.io提供的服務端npm包:框架
npm i socket.io
能夠與 Express 框架配合使用:
const http = require('http') const app = require('express')() const server = http.createServer(app) const io = require('socket.io')(server) server.listen(3000)
也能夠與 Koa 框架配合使用
const http = require('http') const Koa = require('koa') const app = new Koa() const server = http.createServer(app.callback()) const io = require('socket.io')(server) server.listen(3000)
使用起來就是這麼簡單。接下來就能夠寫業務邏輯啦
io.on('connect', client => { // client 便是鏈接上來的一個客戶端 console.log(client.id) // id 是區分客戶端的惟一標識 client.on('disconnect', () => {}) // 客戶端斷開鏈接時調用(多是關掉頁面,網絡不通了等) })
connect
和 disconnect
是 socket.io 內置的事件類型,用於在客戶端鏈接和斷開的時候作一些事情。
在客戶端創建鏈接時須要把他們加入到一個房間裏去,相似建立了一個聊天室
console.log(client.id) + client.join('KPL') // 將客戶端加入到 KPL 房間內 client.on('disconnect', () => {})
緊接着瑤進來秒發了首條消息:我打野,不給就送
服務器在收到這條振奮人心的消息後須要當即同步給其餘四位隊友
client.join('KPL') + client.on('talk', message => { + client.to('KPL').emit('talk', message) // 發送給房間裏的每一個人,除了發送者 + }) client.on('disconnect', () => {})
服務端的功能到這基本上就開發完了。建立了一個房間,並在收到成員消息時當即同步給房間裏的其餘成員
socket.io 爲客戶端提供了另外一個npm包,直接安裝
npm i socket.io-client
接下來就能夠在頁面上創建到服務器的鏈接啦
import io from 'socket.io-client' const socket = io() // 創建鏈接
向服務器發送消息
const socket = io() + socket.emit('talk', '我打野,不給就送')
接收服務器發來的消息
const socket = io() + socket.on('talk', message => { + })
李白看到了瑤的消息,強忍住問候對方家人的衝動,像哄那啥似地說道:
socket.on('talk', message => { + socket.emit('talk', '你買個石頭騎在我頭上他不香麼') })
客戶端的功能到這基本上也開發完了。核心api就是on和emit用於收發消息,既簡單又優雅。
至此一個能夠實時發送接收消息的聊天室就完成了,雖然簡陋,但核心功能完備。
瑤最終倔強地打了野,李白選擇了上路,3分鐘被對面捶到高地,后羿在家裏等鳥,呂布和貂蟬躲在藍buff旁邊的草叢裏聊天,就這樣在李白和瑤互相拉票舉報對方的全局消息中游戲結束