Nginx + Node.js 利用Socket.IO實現前後端實時通訊

在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');
});


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章