余為前端菜鳥,感姿勢水平匱乏,難觀前端之大局。遂決定循前端知識之脈絡,以興趣為引,輔以幾分堅持,望於己能解惑致知、於同道能助力一二,豈不美哉。
本系列**及文件均在 此處
最簡單的實現方式,由客戶端定時向服務端請求資料
簡單實現
// 設定定時器,每秒向伺服器請求資料
複製**
評價
最簡單,但是請求次數太多,每次都要建立連線,對伺服器壓力也很大,大部分時間資料是沒有更新的,浪費頻寬。
服務端接收客戶端請求後暫時掛起,等待資料更新,有資料更新則響應,否則等到達到服務端設定的時間限制後再響應。客戶端接收到響應後會再發出請求,重新建立連線,如此往復。
簡單實現
ajax = () => \n$`
// 重新建立連線
ajax()
}} xhr.send()
}window.onload = () =>
複製**
//
document.getelementbyid("sub").onclick = () => `)
}複製**
// 使用eventemitter進行事件監聽
const eventemitter = require('events').eventemitter
const messagebus = new eventemitter()
messagebus.setmaxlisteners(100)
if (ctx.request.url === '/test') )
})ctx.body = result
} // 接收到message,觸發事件
if (ctx.request.url === '/message')
})複製**
評價
減少了請求次數,但服務端掛起依然是資源浪費。輪詢與長輪詢都是服務被動型,都是由客戶端發起請求。
具體**見 github
sse(server-sent events)是h5新增的功能,允許服務端主動向客戶端推送資料。
簡單實現
// 客戶端會在連線失敗後預設重連
const source = new eventsource('/sse')
// 預設為message,這裡的test1為自定義
source.addeventlistener('test1', (res) => , false)
source.onopen = () =>
source.onerror = (err) =>
// source.close(); // 用於關閉連線
複製**
const readable = require('stream').readable
// 建立自定義流
function
rr() {}
rr.prototype = object.create(new readable());
rr.prototype._read = function (data) {}
if (ctx.request.url === '/sse') )
let stream = new rr()
let count = 1
stream.push(`event: test1\ndata: $)}\n\n`)
// 返回的訊息格式有要求,這裡返回流是因為koa特殊
// 如果不是流會呼叫res.end(buffer),結束http響應
ctx.body = stream
// 多次主動響應,共用乙個連線
const timer = setinterval(() => )}\n\n`)
if (count > 5)
ctx.body = stream
}, 2000)
}複製**
返回的訊息格式應包含這幾個字段
id: 1
// 事件id
event: test1 // 自定義事件,不設定則預設為message
data: // 資料
retry : 10000
// 重連時間
複製**
評價
與前兩者一樣基於http協議,相比於長輪詢,不需要客戶端後續請求,只需要維持乙個請求,後續服務端主動推送,且實現也比較簡單。
具體**見 github
websocket是有別於http的一種新協議,誕生已有十年之久。websocket握手階段採用http協議,沒有同源限制,識別符號為ws
簡單實現
// 原生寫法
const ws = new websocket('ws:')
ws.readystate 0 正在連線 1 已連線 2 正在關閉 3 已關閉
ws.onopen = (evt) =>
ws.onmessage = (evt) => `)
ws.close()
}// socket.io-client
// 服務端用的socket.io,客戶端不用相應的client會有問題
const ws = io('ws:');
ws.on('connect', (evt) => )
ws.on('message', (evt) => `)
ws.close()
});ws.on('disconnect', () => );
複製**
// with koa
const io = require('socket.io')(server)
io.on('connection', (socket) => );
});server.listen('5001')
複製**
評價
使用起來非常簡單,在單個tcp連線上實現客戶端和服務端之間的全雙工通訊,效能在幾者中最好,後續想寫聊天室玩的時候再來搞搞。
web即時通訊其實要解決的乙個是效能問題,乙個是效率問題。效能上像長輪詢和短輪詢都是比較差的,效率我理解體現在實時性和主動性上。長連線和websocket都可以實現服務端主動推送,websocket實現的是雙方你來我往的雙工通訊,更適用於即時通訊的場景。具體做這方面東西肯定會碰到一些坑的,這裡淺嘗輒止,以後有機會接觸再做深入。
雖發表於此,卻畢竟為一人之言,又是每日學有所得之筆記,內容未必詳實,看官老爺們還望海涵。
日拱一卒(一)
layer list 用來多個圖層堆疊顯示的 在drawable資料夾下建立乙個xml檔案。比如 background.xml 另外在layout檔案中指定background屬性這樣就會載入pic1和pic2這兩張。imageview android background drawable bac...
日拱一卒(十四)
git 初識 1.安裝 linux sudo apt get install git core 2.建立 倉庫 linux下開啟shell,windows開啟git bash 1 配置下身份 git config global user.name tony git config global use...
日拱一卒(三十)
迪公尺特法則 lod 如果兩個類不能彼此直接通訊,那麼這兩個類就不應到發生直接的作用。如果其中乙個類需要呼叫另一類的某乙個方法的話,可以通過第三方 這個呼叫。白話 android中intent類就是這個很好的例項,activity,service之間設計就是這樣的松耦合,他們不直接通訊,而是用int...