最近要把一個(gè)即時(shí)通信部署到web端靖榕,原本要用WebSocket标锄,之后在查找WebSocket的時(shí)候看到了Socket.IO這個(gè)東東,要比WebSocket的難度小了很多茁计,還支持多種連接方式料皇,于是果斷換成了Socket.IO。
以下內(nèi)容為個(gè)人理解星压,如有錯(cuò)誤践剂,歡迎指正。
Socket.IO封裝了前端和后端的全部?jī)?nèi)容娜膘,能夠很方便的開(kāi)發(fā)出前后端一體的長(zhǎng)鏈接的網(wǎng)站逊脯。這里我們主要實(shí)現(xiàn)的是Socket.IO的客戶端部分,我們的服務(wù)端使用Java語(yǔ)言進(jìn)行開(kāi)發(fā)竣贪。
使用Socket.IO需要安裝node和npm军洼,在命令行中輸入:
npm install socket.io
因?yàn)槭窃诳蛻舳耸褂肧ocket.IO所以我們需要在使用Scokect.IO的頁(yè)面添加文件引用巩螃,引用socket.io.js
文件,這個(gè)文件我們可以選擇官方提供的文件:
<script src="https://cdn.socket.io/socket.io-1.2.1.js"></script>
但是我們建議使用自己服務(wù)器上部署的版本匕争,如果是服務(wù)端使用node.js編寫使用Socket.IO實(shí)現(xiàn)服務(wù)端長(zhǎng)鏈接功能的話避乏,這樣做能夠和服務(wù)端的版本保持一致。使用自己服務(wù)端生成的文件應(yīng)該這樣引用文件:(socket.io.js
文件由服務(wù)端自動(dòng)編譯生成)
<script src="/socket.io/socket.io.js"></script>
這里由于我們的服務(wù)器是由Java編寫的汗捡,所以我們引用官方提供的socket.io.js
文件淑际。
socket.io.js
文件提供了一個(gè)全局的變量io
,通過(guò)io
我們可以對(duì)socket進(jìn)行操作扇住。
創(chuàng)建一個(gè)socket
創(chuàng)建一個(gè)socket鏈接春缕,我們使用io
中的connect
方法:
var socket = io.connect('/');
socket.on('connect',function(){
//連接成功
});
socket.on('disconnect',function(data){
//連接斷開(kāi)
});
connect
函數(shù)可以接受一個(gè)url參數(shù),即要建立鏈接的url艘蹋,url可以是完整的網(wǎng)絡(luò)路徑锄贼,也可以是相對(duì)路徑,也可以不傳女阀,如果是相對(duì)路徑則是相對(duì)于當(dāng)前頁(yè)面主機(jī)的相對(duì)路徑宅荤,如果未傳url則是與當(dāng)前頁(yè)面的路徑建立socket鏈接。
還可以使用一個(gè)更簡(jiǎn)單的方法建立鏈接:
var socket = io('/');
socket.on('connect',function(){
//連接成功
});
socket.on('disconnect',function(data){
//連接斷開(kāi)
});
使用io
直接創(chuàng)建的這種方式后面參數(shù)還可以傳入對(duì)socket的設(shè)置:
設(shè)置參數(shù)名 | 設(shè)置參數(shù)類型 | 默認(rèn)值 | 設(shè)置說(shuō)明 |
---|---|---|---|
reconnection | bool | true | 是否重連 |
reconnectionDelay | int | 1000 | 多長(zhǎng)時(shí)間后重新連接(ms) |
reconnectionDelayMax | int | 5000 | 重新連接的最大等待時(shí)間(ms) |
timeout | int | 20000 | 連接超時(shí)的時(shí)間(ms) |
設(shè)置參數(shù)采用鍵值對(duì)的方式進(jìn)行設(shè)置浸策。
設(shè)置中我們還可以個(gè)傳遞參數(shù)冯键,比如初始化設(shè)置,個(gè)人信息等:
var socket = io.connect('/',{ _query:'sid=123456' });
監(jiān)聽(tīng)socket
上面的創(chuàng)建socket連接的例子中我們已經(jīng)使用了socket的監(jiān)聽(tīng)庸汗。
socket的監(jiān)聽(tīng)采用on
方法來(lái)實(shí)現(xiàn)惫确。
on
方法有兩個(gè)參數(shù),第一個(gè)參數(shù)是要監(jiān)聽(tīng)的事件蚯舱,第二個(gè)參數(shù)是監(jiān)聽(tīng)到事件后要執(zhí)行的回調(diào)方法改化。
能夠監(jiān)聽(tīng)的事件有:
事件名稱 | 事件說(shuō)明 | 事件回調(diào)參數(shù)說(shuō)明 |
---|---|---|
connect | 連接成功的事件 | 無(wú)參數(shù) |
connect_failed | 連接失敗的事件 | 參數(shù)Object,里面包含錯(cuò)誤信息 |
disconnect | 斷開(kāi)連接的事件 | 無(wú)參數(shù) |
connecting | 正在鏈接的事件 | 無(wú)參數(shù) |
error | 連接錯(cuò)誤事件處理 | |
connect_timeout | 連接超時(shí)的事件 | 無(wú)參數(shù) |
reconnect | 成功重新連接的事件 | 參數(shù)Number枉昏,重連的次數(shù) |
reconnecting | 正在重新連接 | 參數(shù)Number陈肛,重連的次數(shù) |
reconnect_failed | 重新連接失敗 | 無(wú)參數(shù) |
socket發(fā)送和接受消息
socket提供TCP的消息發(fā)送和接收。
消息發(fā)送使用send
接口:
socket.send('hello world!');
消息接收需要監(jiān)聽(tīng)message
接口
socket.on('message',function(data){
//收到消息
console.log(data);
});
消息的接收和發(fā)送建議寫在connect
的事件監(jiān)聽(tīng)器中兄裂。
socket命名空間(房間/分組)
建立鏈接時(shí)我們可以指定將這個(gè)socket放置在某一個(gè)路徑下句旱,這個(gè)路徑下的socket將和其他路徑下的socket互相不干擾。
var socket = io.connect('/chat');
這將會(huì)極大的方便服務(wù)端的廣播(推送)懦窘,服務(wù)端可以在特定的房間內(nèi)發(fā)送廣播(推送)前翎,而在其他房間內(nèi)的socket則不會(huì)接收到該廣播(推送)。
socket中間件
這個(gè)中間件部分將在之后進(jìn)行詳細(xì)講解畅涂,現(xiàn)在只放置一個(gè)身份驗(yàn)證港华,如果沒(méi)有cookies則拋出錯(cuò)誤。
io.use(function(socket, next){
if (socket.request.headers.cookie) return next();
next(new Error('Authentication error'));
});
參考資料:
- Socket.IO:http://socket.io/docs/#
- 匯智網(wǎng)午衰,《實(shí)時(shí)通訊socket.io》:http://www.hubwiz.com/course/543b9914032c781494012b65/
`