標籤:style blog http color strong os
說到學習Socket.IO,就不得不先說說WebSocket。
WebSocket可以說是一種協議,它建立在無狀態的HTTP協議基礎之上。從字面的意思來理解,就是將TCP的Socket(通訊端)應用在了HTTP中,從而使通訊雙方建立起一個保持在活動狀態串連通道,並且是一個全雙工系統(兩個裝置之間同時進行雙向通訊)。
與Ajax不同,它並非面向請求和響應,而是可以直接通過send方法進行訊息傳遞。WebSocket可以說是Socket.IO的一個子集,Socket.IO的底層實現其實有5種方式,WebSocket只是其中一種。在預設的情況下,我們建立的socket.io串連,底層也是調用websocket的執行個體。當我們io.connect()建立一個socket串連的時候,返回的是namespace執行個體,namespace執行個體中又有個socket執行個體,當建立一個串連,或者發送一條訊息的時候,namespace->socket->transport->websocket(xhrpolling...),其實發送一條訊息真正的寄件者還是底層的websocket或是xhrpolling或其他的幾種,而socket.io只是一個召集人,當我們需要建立串連的時候,它自己會在其內部挑選一種串連方式,然後實現串連。
WebSocket的工作方法:
- 伺服器端:初始化伺服器並將websocket.io綁定到上面,然後監聽事件,把訊息send到用戶端。
- 用戶端:初始化WebSocket並和伺服器建立串連,發送資訊。
Socket.IO和WebSocket的比較:
- Socket.IO 訊息的傳遞是基於傳輸的,但不全部依靠 WebSocket,支援絕多的瀏覽器和裝置,包括 IE6 和 iOS ,而 WebSocket 屬於 HTML5 的範疇,早期的瀏覽器不支援。
- Socket.IO 提供了可靠的事件機制,它監聽的是 connect 和 disconnect 事件,而不是 open 和 close 事件。
- Socket.IO 串連丟失時預設自動重連,WebSocket 一般要重新整理瀏覽器。
- Socket.IO 支援你像WebSocket那樣傳輸簡單文本資訊,還可以通過分發(emit) 和監聽(listen)事件來進行JSON資料的分發。
- Socket.IO 支援在單個串連中利用命名空間來區分各種訊息。
- Socket.IO 可以方便地進行廣播,不用自己定義廣播機制。
Socket.IO的工作方法:socket.io最主要的是emit和on兩個函數
- socket.emit提交(發出)一個事件,事件名稱可以自訂,也有一些預設的事件(connection,message,disconnect),緊接著是一個對象,表示向該socket發送的內容。
- socket.on接收一個事件,緊接著是收到事件調用的回呼函數,其中data是收到的資料。
- 內建預設的事件名例如,io.on函數接受"connection"作為用戶端發起串連的事件,當串連成功後,調用帶有socket參數的回呼函數,“disconnect”表示用戶端串連斷開,“message”表示收到訊息等等。自訂的事件名稱,盡量不要跟Socket.IO中內建的預設事件名重名,以免造成不必要的麻煩。
- 伺服器端:將socket.io綁定到常規的http.Server上,
var app = require(‘express‘)();var server = require(‘http‘).Server(app);var io = require(‘socket.io‘)(server);server.listen(80);
設定監聽器
io.on(‘connection‘, function (socket) { socket.emit(‘news‘, { hello: ‘world‘ }); socket.on(‘my other event‘, function (data) { console.log(data); });});
- 用戶端:當Socket.IO被綁定到http.Server上時,會自動攔截以 /socket.io 開頭的URL,並重新導向。socket.io.js實際放在了伺服器端的node_modules檔案夾中。你也可以把這個檔案拷貝到本地,使它成為用戶端的js檔案,這樣就不用每次都向Node伺服器請求,增強穩定性。
<script src="/socket.io/socket.io.js"></script><script> var socket = io(); // TIP: io() with no args does auto-discovery socket.on(‘connect‘, function () { // TIP: you can avoid listening on `connect` and listen on events directly too! socket.emit(‘ferret‘, ‘tobi‘, function (data) { console.log(data); // data will be ‘woot‘ }); });</script>
常用API:
向所有用戶端發送訊息:io.emit
// the following two will emit to all the sockets connected to `/`io.sockets.emit(‘hi‘, ‘everyone‘); // v0.9的,v1.0還支援io.emit(‘hi‘, ‘everyone‘); // 簡短形式,推薦用這個
進入一個房間,向房間發送訊息(自己也能收到),離開房間:socket.join, io.to, socket.leave
io.on(‘connection‘, function(socket){ socket.join(‘some room‘); io.to(‘some room‘).emit(‘some event‘): // in和to實現相同效果,io.in().emit();
socket.leave(‘some room‘);});
向一個房間廣播訊息(自己收不到訊息):socket.broadcast.to(‘some room‘).emit(‘message‘); room換成id
io.on(‘connection‘, function(socket){ socket.on(‘say to someone‘, function(id, msg){ socket.broadcast.to(id).emit(‘my message‘, msg); // id為socket#id });});
當成WebSocket來用:(用戶端)socket.send(‘hi‘),(伺服器)用socket.on(‘message‘, function(data){})來接收。
參考資料:http://socket.io/docs/
http://raytaylorlin.com/Tech/web/Nodejs/socket-io-tutorial/
http://blog.csdn.net/jiangcs520/article/details/17287531