在HTML5的WebSocket以及HTTP2 出現之前,我們實現如網頁聊天這種前後端實時通訊的功能只能是通過AJAX的方式了,無論是輪詢也好,長輪詢也罷。而後來者,WebSocket、HTTP2.0 更多的是在TCP運輸層之上進行了改良,實現前後端的雙向通信。比如WebSocket,在建立之前,客戶端會和服務端建立一次http“握手”,之後就是基於TCP通信了。
HTML5提供的WebSocket API可以說爲我們實現前後端實時雙向通信提供了很大的便利。但我們今天的主角是Socket.IO 又是什麼呢?Socket.IO是Node.js的開源項目,簡單來講,Socket.IO = long polling(長輪詢)+WebSocket. 因此它可以在大部分瀏覽器上運行,即使瀏覽器不支持WebSocket,它也可以通過自動切換到long polling的方式進行實現。這裏,longpolling相當於一個polyfill。但是,Socket.IO的API的書寫仍能夠保持WebSocket的簡潔,這就是Socket.IO的優勢。
本文提供了一個Nginx + Node.js的解決方案。首先,給出我們這裏的一個具體的應用場景。下面的“與我相關”,大家都非常的熟悉。社交網絡裏面如果有人給你點贊,評論,轉發那個小紅點都會+1.這個時候就需要結合我們上面提到的,需要使用Socket.IO。
這裏我們從後到前來講解,分別從Node.js, Nginx, Web前端三個方面來講解。其中會涉及到我遇到的一些技術細節,供我個人記錄,也供大家參考。
Node.js
package.json
{
"name":"XXX",
"version":"0.0.1",
"dependencies":{
"express":"^2.5.1",
"socket.io":"^1.0",
"redis": "^0.7.1"
}
}
需要使用express,socket.io, redis(數據來源)。
Server.js
var app = require('express').createServer(),
io = require('socket.io').listen(app),
redis = require('redis');
var redisClient = redis.createClient('6379', '127.0.0.1');
app.listen(3000);
io.sockets.on('connection', function (socket) {
//發送消息給客戶端
socket.emit('ping', '');
//監聽客戶端發來的消息
socket.on('userId', function (data) {
redisClient.get(data, function(error, res){
if(error) {
console.log(error);
} else {
socket.emit('pong', res);
}
});
console.log(data);
});
});
Nginx:
nginx.conf
location ~* \.io {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Web前端:
首先需要引入這個包
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.0/socket.io.js"></script>
var socket = io.connect('http://YOUR-DOMAIN-NAME');
// 監聽服務端消息
socket.on(ping, function (data) {
console.log(data);
//向服務端推送消息
socket.emit('pong','111');
});