SocketIOæ¯å¨å®¢æ·ç«¯åæå¡ç«¯ä¹é´å»ºç«çååéä¿¡æ°æ®äº¤æ¢ææ¯ï¼åºå±ä½¿ç¨EngineIOãSocketIOçç客æ·ç«¯ä½¿ç¨Engine.IO-Clientï¼æå¡ç«¯ä½¿ç¨Engine.IOå®ç°ã
SocketIOå¦ä½å·¥ä½
å½ä¸ä¸ªæµè§å¨å°è¯å»ºç«SocketIOæ¶ï¼SocketIOé¦å 使ç¨xhr-pollingå建ä¸ä¸ªé¿è½®è¯¢ãé¿è½®è¯¢ä¸æ¦å»ºç«ï¼å®å°å级为WebSocketè¿æ¥ã
SocketIOåºå±æ¯ä½¿ç¨EngineIOåºå®ç°çï¼è¿ä¸ªåºä½¿ç¨WebSocketåXMLHttprequestå°è£ äºä¸å¥èªå·±çSocketåè®®ï¼ææ¶å« EIO Socketï¼ãä¸ä¸ªå®æ´ç EIO Socket å æ¬å¤ä¸ª XHR å WebSocket è¿æ¥.
客æ·ç«¯
EIO Socket éè¿ä¸ä¸ª XHR (XMLHttprequest) æ¡æãå端åéä¸ä¸ª XHRï¼åè¯æå¡ç«¯æè¦å¼å§ XHR é¿è½®è¯¢äºãå端è¿åçæ°æ®éé¢å æ¬ä¸ä¸ª open æ å¿(æ°å 0 表示), 以åsid å upgrades åæ®µï¼pingæ¶é´é´éï¼pingè¶ æ¶æ¶é´ã
0{
"sid": "8b7ab1ae-fbcf-4d23-8192-3c14a2a90721",
"upgrades": [
"websocket"
],
"pingInterval": 10000,
"pingTimeout": 60000
}
sid æ¯æ¬æ¬¡ EIO Socket çä¼è¯ IDï¼å ä¸ºä¸æ¬¡ EIO Socket å
å«äºå¤ä¸ªè¯·æ±ï¼èå端åä¼åæ¶è¿æ¥å¤ä¸ª EIO Socketï¼sid çä½ç¨å°±ç¸å½äº SESSION IDã
å¦ä¸ä¸ªå段 upgradesï¼æ£å¸¸æ
åµä¸æ¯ ['websocket']ï¼è¡¨ç¤ºå¯ä»¥æè¿æ¥æ¹å¼ä»é¿è½®è¯¢åçº§å° WebSocketã
å端å¨åé第ä¸ä¸ª XHR çæ¶åå°±å¼å§äº XHR é¿è½®è¯¢ï¼è¿ä¸ªæ¶åå¦æææ¶åæ°æ®çéæ±ï¼æ¯éè¿é¿è½®è¯¢å®ç°çãæè°é¿è½®è¯¢ï¼æ¯æå端åéä¸ä¸ª requestï¼æå¡ç«¯ä¼çå°ææ°æ®éè¦è¿åæ¶å response. å端æ¶å° response å马ä¸åéä¸ä¸æ¬¡ requestãè¿æ ·å°±å¯ä»¥å®ç°ååéä¿¡ã
å端æ¶å°æ¡æç upgrades åï¼EIO 伿£æµæµè§å¨æ¯å¦æ¯æ WebSocketï¼å¦ææ¯æï¼å°±ä¼å¯å¨ä¸ä¸ª WebSocket è¿æ¥ï¼ç¶åéè¿è¿ä¸ª WebSocket 徿å¡å¨å䏿¡å 容为 probe, ç±»å为 ping çæ°æ®ãå¦æè¿æ¶æå¡å¨è¿åäºå 容为 probe, ç±»å为 pong çæ°æ®ï¼åç«¯å°±ä¼æåé¢å»ºç«ç HTTP é¿è½®è¯¢åæï¼åé¢åªä½¿ç¨ WebSocket ééè¿è¡æ¶åæ°æ®
EIO Socket çå½å¨æå ï¼ä¼é´é䏿®µæ¶é´ ping - pong 䏿¬¡ï¼ç¨æ¥æµè¯ç½ç»æ¯å¦æ£å¸¸ã

è¿æ¯ WebSocket 帧çç»æï¼ç»¿è²æ¯åéï¼ç½è²æ¯æ¥æ¶ãåé¢çæ°åæ¯æ°æ®å ç±»åï¼2 æ¯ ping, 3 æ¯ pong, 42æ¯ message
æå¡ç«¯
æå¡ç«¯ä½¿ç¨ ws åºå®ç° WebSocket åè®®ãhttp://socket.io æå¡å¯å¨æ¶ï¼ä¼å å¯å¨ä¸ä¸ª ws æå¡ãhttp://socket.io ä¼çå¬ HTTP æå¡å¨ç upgrade å request äºä»¶ãå½ upgrade äºä»¶è§¦åæ¶ï¼è¯´æå¯è½æ¯ WebSocket æ¡æï¼å ç®åæ ¡éªä¸ï¼ç¶åæè¯·æ±äº¤ç» ws æå¡è¿è¡å¤çï¼æ¿å° WebSocket 对象ãå½ request äºä»¶è§¦åæ¶ï¼æ ¹æ® url è·¯å¾å¤ææ¯ä¸æ¯ http://socket.io ç XHR 请æ±ï¼æ¿å° res å res 对象ãè¿æ ·å°±å¯ä»¥æ£ç¡®æ¥æ¶åè¿å客æ·ç«¯æ°æ®äºï¼å ·ä½å¤çè¿ç¨åå端é¨åæ¯å¯¹åºçã
示ä¾ä¸SocketIOè¿è¡è天
æå¡å¨
æå¡å¨éè¦å®è£ node.js,æä»¬ä½¿ç¨Expressç®å设置
使ç¨ä»¥ä¸å½ä»¤å建ä¸ä¸ªæ°æä»¶å¤¹:
mkdir socket.io-example
cd socket.io-example
npm install socket.io express
å®è£ æå¡å¨å¹¶å¯¼å ¥æéçç¨åºå ã
const app = require("express")();
const http = require("http").createServer(app);
const io = require("socket.io")(http);
å°æå¡å¨æ ¹ç®å½è®¾ç½®ä¸ºindex.html
app.get("/", (req, res) => res.sendFile(__dirname + "/index.html"));
设置SocketIOç龿¥å»ºç«äºä»¶ï¼è¿éæä»¬åªæå°ä¸æ¡log
io.on("connection", function(socket) { console.log(âsocket connectedâ); });
设置æå¡å¨ä¾¦å¬ç«¯å£ä¸º3000
http.listen(3000, () => console.log("listening on http://localhost:3000"));
è¿è¡å½ä»¤node index.jsï¼ç¶å卿µè§å¨ä¸æå¼é¡µé¢ã
客æ·ç«¯
å¨é¡µé¢ä¸å¯¼å ¥SocketIOèæ¬
è¿æ ·ï¼ä¾¿å»ºç«èµ·äºä¸ä¸ªSocketIOè¿æ¥ã
æå¡å¨
卿å¡å¨å é¨ï¼æä»¬ä½¿ç¨io.emit()åææè¿æ¥ç客æ·ç«¯åéæ¶æ¯ï¼å½æç¨æ·è¿æ¥å°æå¡å¨æ¶ï¼ä»¥ä¸ä»£ç å°å¯¹æææå¡å¨è¿è¡éç¥ï¼å æ¬è¿æ¥è æ¬äººã
io.on("connection", function(socket) { io.emit(âuser connectedâ); });
å¦æä½ æ³åé¤äºè¿æ¥è ä¹å¤çææäººå¹¿æï¼ä½ å¯ä»¥ä½¿ç¨
socket.broadcast.emit()ã
卿¤åºç¡ä¸ï¼æä»¬è¿å¯ä»¥å¯¹å®¢æç«¯åéçæ¶æ¯æ·»å çå¬å¨ï¼å¹¶å°ååºæ¶æ¯åéç»ææç¨æ·ã
io.on("connection", function(socket) {
io.emit(âuser connectedâ); socket.on(âmessage", function(msg) {
io.emit("message", msg);
});
});
以ä¸å®ä¾æ¾ç¤ºäºæä¹å°è¿äºäºä»¶æ·»å å°å®¢æ·ç«¯ã
客æ·ç«¯
å¨index.htmlä¸å¼å ¥æä»¬çèæ¬ï¼åæ¶å建ç®åçè¡¨åæ¶æ¯åæ¾ç¤ºæ¶æ¯ç容å¨ã
Socket.io Example Our Socket.io Chat Application
Messages
åæ·»å ä¸äºå ¶ä»é»è¾
è¿å ¶ä¸æéè¦çæ¯socket.on(event,callback)åè½ã彿å¡å¨ååºçäºä»¶ä¸æä»¬è®¾ç½®çâeventâå¹é æ¶ï¼å°è§¦ååè°ï¼è¿æ¶å°å¨å±å¹ä¸æ¾ç¤ºæ¶æ¯ã
ç»´æ¤åæä½SocketIO
ç»¼ä¸æè¿°ï¼SocketIOå ¥é¨ç¸å¯¹ç®åï¼åªéè¦ä¸ä¸ªNode.jsæå¡å¨å³å¯å¨å ¶ä¸è¿è¡ã妿è¦å¼å§ä¸ºæéæ°éçç¨æ·ä½¿ç¨å®æ¶åºç¨ç¨åºï¼åSocket.IOæ¯ä¸ä¸ªä¸éçéæ©ãå¤§è§æ¨¡å·¥ä½æ¶ä¼åºç°é®é¢ã䏾便¥è¯´ï¼æ¨è¦å»ºç«ä¸ä¸ªCRM类似çåºç¨ç¨åºï¼å¯å®ç°ä¼ä¸ä¹é´çéä¿¡ãSocketIOåºäºå¼æ¥ç½ç»åºæå»ºï¼å°ä¼å¢å æå¡å¨è´è½½ãç»´æä¸ç¨æ·çè¿æ¥ä»¥ååéåæ¥æ¶æ¶æ¯ä¼å¢å æå¡å¨ååï¼å¹¶ä¸å¦æå®¢æ·ç«¯å¼å§éè¿SocketIOåé大鿰æ®ï¼å®å°ä»¥æ°æ®åçå½¢å¼ä¼ è¾æ°æ®ï¼å¨ä¼ è¾æ°æ®åä¼ è¾å®æ¯æ¶éæ¾èµæºãå æ¤ï¼å½æ¨çåºç¨ç¨åºåå¨å¤§éç¨æ·å¹¶ä¸æå¡å¨è¾¾å°å ¶æå¤§è´è½½æ¶ï¼æ¨éè¦å¨å¤ä¸ªæå¡å¨ä¸å¯¹è¿æ¥è¿è¡è´è½½åè¡¡ï¼å¦åå¯è½ä¼ä¸¢å¤±éè¦ä¿¡æ¯ã
ä¸å¹¸çæ¯ï¼è¿ä¸åªæ¯æ·»å å ¶ä»æå¡å¨é£ä¹ç®åã奿¥åæ¯æå¡å¨å客æ·ç«¯ä¹é´ç弿¾è¿æ¥ãæå¡å¨ä» ç¥éç´æ¥ä¸å ¶è¿æ¥ç客æ·ç«¯ï¼èä¸ç¥éä¸å ¶ä»æå¡å¨è¿æ¥ç客æ·ç«¯ãåå°ä¼è¯çåè½ï¼å设æ¨å¨æå¤ªæå¡å¨ä¸æ³åææç¨æ·å¹¿ææäººå å ¥èå¤©çæ¶æ¯ï¼é£ä¹å¯¹äºè¿æ¥å°å ¶ä»æå¡å¨çç¨æ·ï¼åä¸ä¼æ¶å°æ¤æ¶æ¯ã
è¦è§£å³æ¤é®é¢ï¼æ¨éè¦æ¥æä¸ä¸ªæ¶æ¯è®¢é å叿å¡ï¼ä¾å¦Redisï¼ã该æå¡å°éè¿éç¥æææå¡å¨å¨æäººå å ¥è天æ¶éè¦åéæ¶æ¯æ¥è§£å³ä¸è¿°é®é¢ãä¸å¹¸çæ¯ï¼è¿æå³çè¦ç»´æ¤ä¸ä¸ªé¢å¤çæå¡ï¼è¯¥æå¡å¾å¯è½éè¦èªå·±çæå¡å¨ã
SocketIOå å«ä¸ä¸ªéé å¨socketio-adapterï¼å¯ä¸åå¸/订é åå¨åæå¡å¨å ±äº«ä¿¡æ¯ãæ¨å¯ä»¥ç¼åèªå·±çéé å¨å®ç°ï¼ä¹å¯ä»¥ä½¿ç¨å®ä»¬ä½ä¸ºRedisçéé å¨ï¼å¹¸è¿çæ¯ï¼Socket.IOæäºéæã
Socket.IOçå ¶ä»å¯é æ§å¢å¼ºå¯è½å æ¬CoreOSï¼å¯å°ä½ç³»ç»ææå为å¨ä¸å硬件ä¹é´åå¸çåå ï¼å¹¶éçè´è½½çå¢å å¼å ¥æ°å®ä¾ã
æ©å±Socket.IOçå¦ä¸ä¸ªé®é¢æ¯ï¼å°½ç®¡WebSocketä¿æè¿æ¥æå¼ï¼ä½å¦æè¿æ¥åéå°è½®è¯¢ï¼åå¨è¿æ¥çå½å¨æä¸ä¼æå¤ä¸ªè¯·æ±ãå½è¿äºè¯·æ±ä¹ä¸è½¬å°å¦ä¸å°æå¡å¨æ¶ï¼æ¨å°æ¶å°é误âå¨WebSocketæ¡ææé´åçéè¯¯ï¼æå¤çååºä»£ç ï¼400âã
SocketIOçéå¶
ä¸ææææ¯ä¸æ ·ï¼éæ©æ£ç¡®çä¸ç§æå³çæç¡®æ¨å¯¹äº§åæªæ¥çææã䏿¨èªå·±å建Socket龿¥ç¸æ¯ï¼SocketIOç¡®å®ä½¿è®¸å¤äºæ å徿´å®¹æï¼ä½æ¯é¤äºä¸é¢æå°çæ©å±é®é¢ä¹å¤ï¼è¿æå±éæ§å缺ç¹ã
é¦å æ¯åå§è¿æ¥æ¯WebSocketsæ´é¿ãè¿æ¯å 为å®é¦å 使ç¨é¿è½®è¯¢åXHRPolling建ç«è¿æ¥ï¼ç¶åå级å°WebSocketï¼å¦æå¯ç¨ï¼ã妿æ¨ä¸éè¦æ¯æè¾æ§çæµè§å¨å¹¶ä¸ä¸æ å¿ä¸æ¯æWebSocketsç客æ·ç«¯ç¯å¢ï¼åå¯è½ä¸éè¦SocketIOçé¢å¤å¼éãæ¨å¯ä»¥éè¿æå®ä» ä¸WebSocketsè¿æ¥æ¥æå¤§ç¨åº¦å°åå°è¿ç§å½±åãè¿å°æ´æ¹ä¸WebSocketçåå§è¿æ¥ï¼ä½æ¯ä¼å ³éå¤éæ¹æ¡ã
客æ·ç«¯
Const socket = io({transports: [âwebsocketâ], upgrade: false});
æå¡å¨
io.set("transports", ["websocket"]);
å¨è¿ç§æ åµä¸ï¼å®¢æ·ç«¯ä»å°éè¦ä¸è½½61.2 KBçsocketioJavaScriptæä»¶ã
对äºå ¶ä»ç¹éçæ°æ®ä¼ è¾ï¼ä¾å¦ï¼è§é¢æµä¼ è¾ï¼ï¼Socket䏿¯å¥½çè§£å³æ¹æ¡ã妿è¦å¨æ¤çº§å«ä¸æ¯ææ°æ®äº¤æ¢ï¼åæ´å¥½çè§£å³æ¹æ¡æ¯webRTCææµæ°æ®ä¼ è¾æå¡åï¼Ablyæ¯å ¶ä¸ä¹ä¸ãï¼æ¬æç±ç¯ä¿¡ç¼è¯ï¼è½¬è½½è¯·æ³¨æåºå¤ï¼

