WebSocket 协议给我们提供了一个创建可以支持客户端和服务端进行双向实时通信的web应用程序的方法。相比之前使用的方法,WebSocket(作为HTML5的一部分)可以使我们更容易开的发出这种类型的应用程序。绝大多数的现代浏览器都支持WebSocket,包括火狐,IE,Chrome,Safari以及Opera等,同时,越来越多的服务端框架也开始支持WebSocket了。

对于企业应用来说,我们需要多个WebSocket服务器来保障性能和高可用性,因此我们迫切的需要对WebSocket协议进行负载均衡。NGINX自从1.3版本就开始支持WebSocket了,并且可以为WebSocket应用程序做反向代理负载均衡

WebSocket 和HTTP协议不同,但是WebSocket中的握手和HTTP中的握手兼容,它使用HTTP中的Upgrade协议头将连接从HTTP升级到WebSocket。这使得WebSocket程序可以更容易的使用现已存在的基础设施。例如,WebSocket可以使用标准的HTTP端口 80 和 443,因此,现存的防火墙规则也同样适用。

 

一个WebSockets的应用程序会在客户端和服务端保持一个长时间工作的连接。用来将连接从HTTP升级到WebSocket的HTTP升级机制使用HTTP的Upgrade和Connection协议头。反向代理服务器在支持WebSocket方面面临着一些挑战。一项挑战是WebSocket是一个hop-by-hop协议,所以,当代理服务器拦截到一个客户端发来的Upgrade请求时,它(指服务器)需要将它自己的Upgrade请求发送给后端服务器,也包括合适的请求头。此外,由于WebSocket连接是长时间保持的,所以代理服务器需要允许这些连接处于打开状态,而不是像对待HTTP使用的短连接那样将其关闭。

NGINX 通过在客户端和后端服务器之间建立起一条隧道来支持WebSocket。为了使NGINX可以将来自客户端的Upgrade请求发送给后端服务器,Upgrade和Connection的头信息必须被显式的设置。如下所示:

location /wsapp/ {
    proxy_pass http://wsbackend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

一旦我们完成以上设置,NGINX就可以处理WebSocket连接了。

 
 

NGINX Websockets 举例

这里有一个展示NGINX如何为WebSocket做代理的实例。这个例子将会使用node.js上的一个实现了WebSocket的模块——ws。这个示例在Ubuntu 13.10 和 CentOS 6.5上测试通过,但对于其他系统来说也许需要稍作修改。就这个例子来说,WebSocket服务器的IP地址是192.168.100.10,NGINX服务器的IP地址是192.168.100.20。如果你还没有安装node.js和npm,你可以通过以下命令安装:

对 Debian/Ubuntu 来说:

sudo apt-get install nodejs npm

对 RHEL/CentOS 来说:

sudo yum install nodejs npm

在Ubuntu上,node.js会被安装为 "nodejs",在CentOS中被会安装为"node"。我们在这例子中统一使用"node",所以,我们将会在Ubuntu上创建一个连接来允许我们使用“node”:

ln -s /usr/bin/nodejs /usr/local/bin/node

然后安装 ws:

sudo npm install ws

注意:如果你得到了一个错误:“Error: failed to fetch from registry: ws” ,那么运行下面的命令应该能解决这个问题:

sudo npm config set registry http://registry.npmjs.org/

接下来,你可以再次运行 sudo npm install ws

ws命令来自/root/node_modules/ws/bin/wscat,我们将会把它当做我们的客户端,但是我们需要创建一个程序来做我们的服务端。将下面的代码保存到一个server.js文件中:

console.log("Server started");
var Msg = '';
var WebSocketServer = require('ws').Server
    , wss = new WebSocketServer({port: 8010});
    wss.on('connection', function(ws) {
        ws.on('message', function(message) {
        console.log('Received from client: %s', message);
        ws.send('Server received from client: ' + message);
    });
 });

这个程序可以通过下面的命令执行:

node server.js

 
 

该程序会输出一条初始化消息“Server started”,之后监听8010端口,等待客户端的连接。它会处理收到的所有请求,并且将接收到的消息输出在控制台,之后向客户端返回一条包含该消息的消息。我们希望NGINX去代理这些请求,通过下面的配置便可实现:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
upstream websocket {
    server 192.168.100.10:8010;
}
server {
    listen 8020;
    location / {
        proxy_pass http://websocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

上面的配置会使NGINX监听8020端口,并把接收到的任何请求传递给后端的WebSocket服务器以便恰当的处理WebSocket协议。我们可以使用wscat作为客户端来测试一下:

/root/node_modules/ws/bin/wscat –connect ws://192.168.100.20:8020

上面的命令会通过NGINX代理服务器和WebSocket服务器建立连接,你可以输入你想要发送给服务器的消息,之后服务器会返回一条消息。每当你输入一条消息,你应该可以在服务端看到该消息的输出,之后在客户端会显示一条来自服务端的消息。

 
 

这是一个交互示例:

由此我们可以看到服务端与客户端能够通过作为代理的NGINX通信, 而且消息可以持续进行双向传输直到客户端或服务端断开连接。为了能使NGINX正确处理WebSocket, 只需正确地设置消息头来处理更新从http到WebSocket连接的Upgrade请求

Nginx 作为 WebSockets 代理的更多相关文章

  1. Nginx担当WebSockets代理

    Nginx担当WebSockets代理 英文原文:http://nginx.com/blog/websocket-nginx/ 作者:chszs,转载需注明. 博客主页:http://blog.csd ...

  2. 使用Nginx做WebSockets代理教程

    WebSocket 协议提供了一种创建支持客户端和服务端实时双向通信Web应用程序的方法.作为HTML5规范的一部分,WebSockets简化了开发Web实时通信程 序的难度.目前主流的浏览器都支持W ...

  3. Windos环境用Nginx配置反向代理和负载均衡

    Windos环境用Nginx配置反向代理和负载均衡 引言:在前后端分离架构下,难免会遇到跨域问题.目前的解决方案大致有JSONP,反向代理,CORS这三种方式.JSONP兼容性良好,最大的缺点是只支持 ...

  4. 在ubuntu上面配置nginx实现反向代理和负载均衡

    上一篇文章(http://www.cnblogs.com/chenxizhang/p/4684260.html),我做了一个实验,就是利用Visual Studio,基于Nancy框架,开发了一个自托 ...

  5. nginx的反向代理和负载均衡的一个总结

    之前一直觉的nginx的反向代理和负载均衡很厉害的样子,最近有机会接触了一下公司的这方面的技术,发现技术就是一张窗户纸呀,捅破了啥都明白了! 接下来先看一下nginx的反向代理: 简单的来说就是ngi ...

  6. nginx做反向代理并防盗链

    nginx做反向代理真的非常简单,只需设置location+proxy_pass即可. 防盗链配置有些复杂,需要注意的地方: 在防盗链的location中需要再设置一下proxy_pass(在这里走了 ...

  7. nginx设置反向代理后,页面上的js css文件无法加载

    问题现象: nginx配置反向代理后,网页可以正常访问,但是页面上的js css文件无法加载,页面样式乱了. (1)nginx配置如下: (2)域名访问:js css文件无法加载: (3)IP访问:j ...

  8. 用nginx做反向代理来访问防外链图片

    用nginx做反向代理来访问防外链图片 女儿的博客从新浪搬到wordpress后,发现原来博客上链接的新浪相册的图片都不能访问了,一年的博客内容,一个个去重新上传图片,修正链接也是个大工程.还是得先想 ...

  9. Nginx 笔记与总结(15)nginx 实现反向代理 ( nginx + apache 动静分离)

    在 nginx 中,proxy 用来实现反向代理,upstream 用来实现负载均衡. 例如有两台服务器,nginx 服务器作为代理服务器,执行 .html 文件,apache 服务器上执行 .php ...

随机推荐

  1. Expression Blend实例中文教程(4) - 布局控件快速入门Canvas

    上一篇,我介绍了Silverlight控件被分为三种类型, 第一类: Layout Controls(布局控件) 第二类: Item Controls (项目控件) 第三类: User Interac ...

  2. vue本地设置请求接口及数据

    1.安装axios yarn add axios 2.在入口文件main.js中设置 import { getRequest, postRequest} from './libs/api';//导入 ...

  3. SQL语句表处理

    1.create table:创建表,语法: create table 表格名 ( 列名 数据类型, 列名 数据类型, ...... ) 2.constrain:约束,关键词 NOT NULL. UN ...

  4. PAT 1048. Find Coins

    two sum题目,算是贪婪吧 #include <cstdio> #include <cstdlib> #include <vector> #include &l ...

  5. nginx关于 error_page指令详解.md

    error_page指令解释 nginx指令error_page的作用是当发生错误的时候能够显示一个预定义的uri,比如: error_page 502 503 /50x.html; 这样实际上产生了 ...

  6. 深入理解jQuery插件开发总结(二)

    1,开始 可以通过为jQuery.fn增加一个新的函数来编写jQuery插件.属性的名字就是你的插件的名字: jQuery.fn.myPlugin = function(){ //开始写你的代码吧! ...

  7. 无限滚动条的css布局理解

    一.需求描述 做一个waymo的滚动条,在页面中显示两张图,一共4张图,无限滚动播放. .car{ width: 600px; height: 157px; margin: 100px auto; b ...

  8. div,css&table布局有哪些区别

    DIV+CSS布局与TABLE布局相比,有哪些优点? 1.代码少,页面文件小,下载快 Div+css的布局现在属于国际W3C标准,table不是. 都知道用div的布局代码肯定少,所有的样式都在CSS ...

  9. Python爬虫教程-17-ajax爬取实例(豆瓣电影)

    Python爬虫教程-17-ajax爬取实例(豆瓣电影) ajax: 简单的说,就是一段js代码,通过这段代码,可以让页面发送异步的请求,或者向服务器发送一个东西,即和服务器进行交互 对于ajax: ...

  10. k 近邻算法(k-Nearest Neighbor,简称kNN)

    预约助教问题: 1.计算1-NN,k-nn和linear regression这三个算法训练和查询的时间复杂度和空间复杂度? 一. WHy 最简单最初级的分类器是将全部的训练数据所对应的类别都记录下来 ...