Nginx担当WebSockets代理

英文原文:http://nginx.com/blog/websocket-nginx/

作者:chszs,转载需注明。

博客主页:http://blog.csdn.net/chszs

WebSocket 协议提供了一种创建支持client和服务端实时双向通信Web应用程序的方法。作为HTML5规范的一部分,WebSockets简化了开发Web实时通信程序的难度。

眼下主流的浏览器都支持WebSockets,包含火狐、IE、Chrome、Safari以及Opera等,并且,越来越多的server应用框架也開始支持WebSockets。

要在企业产品中使用WebSockets,为满足高性能和高可用性,须要多个WebSocketserver。负载均衡层须要支持WebSocket协议。

Nginx从1.3版起就開始支持WebSocket协议,并且能够担当WebSocket应用程序的反向代理以及实现负载均衡。

WebSocket协议和HTTP协议不同,可是WebSocket协议的握手和HTTP是兼容的,它使用HTTP的Upgrade协议头将连接从HTTP连接升级到WebSocket连接。

这个特性使得WebSocket应用程序能够非常easy地应用到现有的基础设施。比如,WebSocket应用能够使用标准的80和443 HTTPport,因此能够通过现有的防火墙设施。

WebSockets应用程序会在client和server之间建立一个长连接,使得开发实时应用非常easy。

HTTP的Upgrade协议头机制用于将连接从HTTP连接升级到WebSocket连接。Upgrade机制使用了Upgrade协议头和Connection协议头。反向代理server在支持WebSocket协议方面面临着一些挑战。挑战之中的一个是WebSocket是一个逐段转发(hop-by-hop)协议。因此当代理server拦截到来自client的Upgrade请求时,代理server须要将自己的Upgrade请求发送给后端server,包含适合的请求头。并且。由于WebSocket连接是长连接,与传统的HTTP端连接截然不同,故反向代理server还须要同意这些连接处于打开(Open)状态,而不能由于其空暇就关闭了连接。

Nginx通过在client和后端server之间建立隧道来支持WebSockets通信。为了让Nginx能够将来自client的Upgrade请求发送到后端server。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做代理的。

此例将使用ws模块,它是基于node.js构建的WebSocket实现。Nginx将担当反向代理server,后端server是一个使用了ws和Node.js的简单WebSockets应用。样例使用的命令在Ubuntu 13.10和CentOS 6.5上測试通过。但对于其它操作系统也许须要稍作改动。

就这个样例来说,WebSocketserver的IP地址是192.168.100.10,Nginxserver的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,我们会为client使用它,可是我们须要创建一个程序来作为我们的server。将以下的代码保存到一个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”,之后监听8010port。等待client的连接。

它会处理收到的全部请求,并且将接收到的消息输出在控制台。之后向client返回一条包含该消息的消息。我们希望Nginx去代理client的请求,能够通过以下的配置实现:

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监听8020port,并把不论什么接收到的请求转发给后端的WebSocketserver。让后端server更好地处理WebSocket协议。

我们能够使用wscat作为client来測试一下:

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

上面的命令会通过Nginx反向代理server和后端WebSocketserver建立连接,你能够向server发送随意消息,然后server会返回一条消息。每当你在client发送一条消息,在后端server上能看到该消息的输出,之后在client会显示一条来自服务端的消息。
这是一个交互演示样例:

Server:

Client:

$ node server.js

Server started

wscat –connect ws://192.168.100.20:8020

Connected (press CTRL+C to quit)

> Hello

Received from client: Hello

< Server received from client: Hello

由此我们能够看到client与server能通过Nginx反向代理建立WebSockets通信,并且消息能够持续地进行双向传输。直至client或server断开连接。为了让Nginx能正确处理WebSocket连接,仅仅需正确地设置消息头来处理从HTTP连接升级到WebSocket连接的Upgrade请求。

Nginx担当WebSockets代理的更多相关文章

  1. 使用Nginx做WebSockets代理教程

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

  2. Nginx 作为 WebSockets 代理

    WebSocket 协议给我们提供了一个创建可以支持客户端和服务端进行双向实时通信的web应用程序的方法.相比之前使用的方法,WebSocket(作为HTML5的一部分)可以使我们更容易开的发出这种类 ...

  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. 20155302 2016-2017-2《Java程序设计》第五周学习总结

    20155302 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 异常类从哪里来?有两个来源,一是Java语言本身定义的一些基本异常类型,二是用户通过继承Ex ...

  2. 【译】SQLskills SQL101:Trace Flags、ERRORLOG、Update Statistics

    最近阅读SQLskills SQL101,将Erin Stellato部分稍作整理.仅提取自己感兴趣的知识点,详细内容请阅读原文. 一.Trace Flags推荐开启三个跟踪标记1118.3023.3 ...

  3. Dream Spark ------spark on yarn ,yarn的配置

    <?xml version="1.0"?> <!-- Licensed under the Apache License, Version 2.0 (the &q ...

  4. VCForPython27.msi安装后, 还显示error: Unable to find vcvarsall.bat

    C:\Users\zpc\AppData\Local\Programs\Common\Microsoft\Visual C++ for Python\9.0\VC 增加环境变量: SET VCPYTH ...

  5. 奈奎斯特定理 and 香农定理

    -----------------------整理自<21ic电子网> 奈奎斯特定理(Nyquist's Theorem)和香农定理(Shannon's Theorem)是网络传输中的两个 ...

  6. The project cannot be built until its prerequisite base-service is built. Cleaning and building all projects is recommended

    参考网址:http://chiangfai.iteye.com/blog/2223661,谢谢! 果然如文中所述,close,重新编译即可!

  7. MCM/ICM2018美国大学生数学建模大赛D题翻译

    MCM/ICM2018美国大学生数学建模大赛D题翻译 2018年ICM问题D: 非使用汽油并在使用电力行驶的汽车(电量非空的) 由于环境和经济的原因,全球都在减少使用化石燃料,包括汽车汽油. 无论是受 ...

  8. linux进程的一些日常处理

    linux 下查看一个进程运行路径的方法 在linux下查看进程大家都会想到用 ps -ef|grep XXX 可是看到的不是全路径,怎么看全路径呢? 每个进程启动之后在 /proc下面有一个于pid ...

  9. ​学会用各种姿势备份MySQL数据库

    学会用各种姿势备份MySQL数据库 前言 为什么需要备份数据? 数据的备份类型 MySQL备份数据的方式 备份需要考虑的问题 设计合适的备份策略 实战演练 使用cp进行备份 使用mysqldump+复 ...

  10. SqlServer中 SET DATEFIRST更改

    在 SQL Server 中默认情况下,每周的开始都是从周日开始算起的,如果默认星期一呢? 这里有三种方式可以解决这个问题: 一:直接通过 SET DATEFIRST VALUE 来更改重新生成新的 ...