Nginx 作为 WebSockets 代理
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 代理的更多相关文章
- Nginx担当WebSockets代理
Nginx担当WebSockets代理 英文原文:http://nginx.com/blog/websocket-nginx/ 作者:chszs,转载需注明. 博客主页:http://blog.csd ...
- 使用Nginx做WebSockets代理教程
WebSocket 协议提供了一种创建支持客户端和服务端实时双向通信Web应用程序的方法.作为HTML5规范的一部分,WebSockets简化了开发Web实时通信程 序的难度.目前主流的浏览器都支持W ...
- Windos环境用Nginx配置反向代理和负载均衡
Windos环境用Nginx配置反向代理和负载均衡 引言:在前后端分离架构下,难免会遇到跨域问题.目前的解决方案大致有JSONP,反向代理,CORS这三种方式.JSONP兼容性良好,最大的缺点是只支持 ...
- 在ubuntu上面配置nginx实现反向代理和负载均衡
上一篇文章(http://www.cnblogs.com/chenxizhang/p/4684260.html),我做了一个实验,就是利用Visual Studio,基于Nancy框架,开发了一个自托 ...
- nginx的反向代理和负载均衡的一个总结
之前一直觉的nginx的反向代理和负载均衡很厉害的样子,最近有机会接触了一下公司的这方面的技术,发现技术就是一张窗户纸呀,捅破了啥都明白了! 接下来先看一下nginx的反向代理: 简单的来说就是ngi ...
- nginx做反向代理并防盗链
nginx做反向代理真的非常简单,只需设置location+proxy_pass即可. 防盗链配置有些复杂,需要注意的地方: 在防盗链的location中需要再设置一下proxy_pass(在这里走了 ...
- nginx设置反向代理后,页面上的js css文件无法加载
问题现象: nginx配置反向代理后,网页可以正常访问,但是页面上的js css文件无法加载,页面样式乱了. (1)nginx配置如下: (2)域名访问:js css文件无法加载: (3)IP访问:j ...
- 用nginx做反向代理来访问防外链图片
用nginx做反向代理来访问防外链图片 女儿的博客从新浪搬到wordpress后,发现原来博客上链接的新浪相册的图片都不能访问了,一年的博客内容,一个个去重新上传图片,修正链接也是个大工程.还是得先想 ...
- Nginx 笔记与总结(15)nginx 实现反向代理 ( nginx + apache 动静分离)
在 nginx 中,proxy 用来实现反向代理,upstream 用来实现负载均衡. 例如有两台服务器,nginx 服务器作为代理服务器,执行 .html 文件,apache 服务器上执行 .php ...
随机推荐
- ASP.Net Core MVC 网站在Windows服务器跑不起来
1.vs远程发布到服务器,浏览器访问,报错502 2.打开错误提示提供的网址参考 3.安装runtime,sdk,Hosting Bundle Installer,其他操作 .....发现并没有什么用 ...
- 如何制作Win10系统U盘安装镜像
准备的工具: 1.空间8G以上的U盘一个 2.系统镜像文件(ISO格式)下载:https://msdn.itellyou.cn/ 3.UltraISO 下载:https://cn.ultraiso.n ...
- [android] 练习样式主题自定义activity切换动画
主要练习了自定义样式和主题,继承android系统默认的样式并修改,练习xml定义淡入淡出动画 anim/fade_in.xml <?xml version="1.0" en ...
- 六、mybatis分页插件集成
本文基于上一篇“集成mybatis”内容 1.添加依赖 <!-- mybatis-pageHelper --> <dependency> <groupId>com. ...
- spring_boot 配置
配置pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...
- java时间工具类
在项目中,很多地方需要根据时间获取相应的数据,将时间格式化,或者时间比较等相关操作.一个良好的工具类不仅可以减少代码冗余,还能促进业务处理,加快进度. /** * @author: lxw * @Da ...
- ZT 为什么Java中继承多数是有害的?
大多数好的设计者象躲避瘟疫一样来避免使用实现继承(extends 关系).实际上80%的代码应该完全用interfaces写,而不是通过extends.“Java设计模式”一书详细阐述了怎样用接口继承 ...
- java设计模式之抽象工厂模式学习
工厂模式有个问题就是,类的创建依赖工厂.要想增加一个工厂类,就要修改原来的代码,这违背了闭包原则.所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的 ...
- 模块与包&常用模块
一.模块的使用 模块定义:一系列功能的集合体 分为三大类:1.自定义模块 2.内置模块(比如 time,os,sys) 3.第三方模块 模块的表现形式: 1.使用python编写的py文件 2.已被编 ...
- linux 共享目录
1. 文件上传遇到多物理机多实例时,怎么处理呢? ftp, 文件同步, 目录共享 这里用目录共享来一把. 2. 操作流程 物理机两台 192.168.1.88 192.168.1.166 2.1 服 ...