近日接到需求,須要在「直播後臺監控系統」裏監控直播間的消息。剛接到需求時一臉懵逼,好在隊友給力,Google強大,需求已經上線。現將我完成需求的過程與查閱瞭解到的知識整理出來,僅供參考,若錯誤請指教~~html
WebSocket一種在單個TCP鏈接上進行全雙工通信的協議。WebSocket通訊協議於2011年被IETF定爲標準RFC 6455,並被RFC7936所補充規範,WebSocketAPI被W3C定爲標準。前端
WebSocket 是獨立的、建立在 TCP 上的協議,和 HTTP 的惟一關聯是使用 HTTP 協議的101狀態碼進行協議切換,使用的 TCP 端口是80,能夠用於繞過大多數防火牆的限制。java
WebSocket使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端直接向客戶端推送數據而不須要客戶端進行請求,在 WebSocket API 中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並容許數據進行雙向傳送。node
如今,不少網站爲了實現推送技術,所用的技術都是輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP request,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP request的header是很是長的,裏面包含的數據可能只是一個很小的值,這樣會佔用不少的帶寬和服務器資源。
而比較新的技術去作輪詢的效果是Comet,使用了AJAX。但這種技術雖然可達到雙向通訊,但依然須要發出請求,並且在Comet中,廣泛採用了長連接,這也會大量消耗服務器帶寬和資源。
面對這種情況,HTML5定義了WebSocket協議,能更好的節省服務器資源和帶寬並達到實時通信。git
在實現websocket連線過程當中,須要透過瀏覽器發出websocket連線請求,而後服務器發出迴應,這個過程一般稱爲「握手」(handshaking)。爲第13版且瀏覽器爲Chrome的例子:github
瀏覽器請求:web
GET / HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: example.com Origin: null Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ== Sec-WebSocket-Version: 13
服務器迴應:後端
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s= Sec-WebSocket-Origin: null Sec-WebSocket-Location: ws://example.com/
在請求中的「Sec-WebSocket-Key」是隨機的,服務器端會用這些數據來構造出一個SHA-1的信息摘要。
把「Sec-WebSocket-Key」加上一個魔幻字符串「258EAFA5-E914-47DA-95CA-C5AB0DC85B11」。使用SHA-1加密,以後進行BASE-64編碼,將結果作爲「Sec-WebSocket-Accept」頭的值,返回給客戶端。api
WebSocket提供了一個受歡迎的技術,以替代咱們過去幾年一直在用的Ajax技術,WebSocket API是下一代客戶端-服務器的異步通訊方法,它提供了一個方法能夠從客戶端使用簡單的語法有效地推進消息到服務器。HTML5的WebSocket API:它可用於客戶端、服務器端。並且有一個優秀的第三方API,名爲Socket.IO。 瀏覽器
WebSocket API的用法能夠參照 認識HTML5的WebSocket
Socket.IO的用法參照官方API socket.io/docs
(ps:官方文檔寫得不多,但基本的參數配置仍是寫出來了,若是看了仍是懵逼的話,建議直接斷點進去把Socket的IO對象的屬性方法輸出來看)
ps:對websocket的初步認識,其實我更傾向於知乎上(做者:董可人)這段通俗易懂的理解:
你能夠把 WebSocket 當作是 HTTP 協議爲了支持長鏈接所打的一個大補丁,它和 HTTP 有一些共性,是爲了解決 HTTP 自己沒法解決的某些問題而作出的一個改良設計。在之前 HTTP 協議中所謂的 keep-alive connection 是指在一次 TCP 鏈接中完成多個 HTTP 請求,可是對每一個請求仍然要單獨發 header;所謂的 polling 是指從客戶端(通常就是瀏覽器)不斷主動的向服務器發 HTTP 請求查詢是否有新數據。這兩種模式有一個共同的缺點,就是除了真正的數據部分外,服務器和客戶端還要大量交換 HTTP header,信息交換效率很低。它們創建的「長鏈接」都是僞.長鏈接,只不過好處是不須要對現有的 HTTP server 和瀏覽器架構作修改就能實現。
WebSocket 解決的第一個問題是,經過第一個 HTTP request 創建了 TCP 鏈接以後,以後的交換數據都不須要再發 HTTP request了,使得這個長鏈接變成了一個真.長鏈接。可是不須要發送 HTTP header就能交換數據顯然和原有的 HTTP 協議是有區別的,因此它須要對服務器和客戶端都進行升級才能實現。在此基礎上 WebSocket 仍是一個雙通道的鏈接,在同一個 TCP 鏈接上既能夠發也能夠收信息。此外還有 multiplexing 功能,幾個不一樣的 URI 能夠複用同一個 WebSocket 鏈接。這些都是原來的 HTTP 不能作到的。
先說說項目背景:公司的app裏有直播,相似於新浪app的直播,而「直播後臺監控系統」就是爲了監控各個主播直播的狀況,是否有不當言論等等,目前只有直播的視頻畫面,沒有直播文字,因此須要增長文字監控。
「直播後臺監控系統」後端java開發,一個監控頁面能夠監控4-8個直播間,直播視頻採用了騰訊的播放器,傳送地址 騰訊雲視頻點播服務的網頁播放器(Web SDK)。 雖然api裏有彈幕接口,通過仔細討論,仍然決定採用Socket.IO來作,而且一個監控頁面只創建一個socket連接,監控頁面收到推送消息以後根據直播間的id,直接把消息append到對應直播間.
需求和思路說清楚了,如今直接貼代碼:
首次先在頁面上引入,從源碼能夠看到,socket.io-1.4.0.js已作了兼容,AMD和CMD規範均可以用,
<script src="http://cdn.socket.io/socket.io-1.4.0.js"></script>
此時,Socket.IO在此頁面上是有效的,下面建立Socket而且綁定消息推送,
var socket = io.connect('http://XXX:9092'); //創建socket連接 socket.on('connect', function () { //當socket鏈接成功以後執行function裏面的代碼. socket.emit('registerMonitorRoomEvent', { //註冊監聽事件,將須要監聽的直播房間好發給後臺. roomId : roomId }); }); socket.on('receiveMessageEvent', function (msg) { //收到後端推送的直播消息. liveObj[msg.roomId].onMonitorMessage(msg); //liveObj是前端定義的對象,存儲了全部直播間實例,liveObj[msg.roomId]取到了須要推送消息的直播間,再調用該直播間定義好的onMonitorMessage方法接受消息。 }) //若是須要斷開直播,直接socket.disconnect();
是的,前端代碼就是這麼少。java小白一隻,只能勉強看明白後端寫了什麼,不貼後端代碼了。
socket.io官網上的一個demo,服務端採用node,想要快速看到socket.io各個api效果的,此demo最快。項目傳送 A simple chat demo for socket.io
ps: examples/chat/public/index.html文件裏面的25行,引入的路徑要爲<script src="/socket.io/socket.io.js"></script>。