WebSocket 结合 Nginx 实现域名及 WSS 协议访问
简单了解一下 WebSocket
现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
WebSocket一种在单个 TCP 连接上进行全双工通讯的协议。使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
以上信息摘自维基百科(https://zh.wikipedia.org/wiki/WebSocket)
简单点说,WebSocket 就是减小客户端与服务器端建立连接的次数,减小系统资源开销,只需要一次 HTTP 握手,整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直与客户端保持连接,直到你关闭请求,同时由原本的客户端主动询问,转换为服务器有信息的时候推送。当然,它还能做实时通信、更好的二进制支持、支持扩展、更好的压缩效果等这些优点。
推荐一个知乎上叫 Ovear 的网友关于 WebSocket 原理的回答,嘻哈风格科普文,简直不要更赞了!地址:https://www.zhihu.com/question/20215561/answer/40316953
ws 和 wss 又是什么鬼?
Websocket使用 ws 或 wss 的统一资源标志符,类似于 HTTP 或 HTTPS,其中 wss 表示在 TLS 之上的 Websocket ,相当于 HTTPS 了。如:
ws://example.com/chat
wss://example.com/chat
默认情况下,Websocket 的 ws 协议使用 80 端口;运行在TLS之上时,wss 协议默认使用 443 端口。其实说白了,wss 就是 ws 基于 SSL 的安全传输,与 HTTPS 一样样的道理。
如果你的网站是 HTTPS 协议的,那你就不能使用 ws:// 了,浏览器会 block 掉连接,和 HTTPS 下不允许 HTTP 请求一样,如下图:

Mixed Content: The page at 'https://domain.com/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://x.x.x.x:xxxx/'. This request has been blocked; this endpoint must be available over WSS.
这种情况,毫无疑问我们就需要使用 wss:\\ 安全协议了,我们是不是简单的把 ws:\\ 改为 wss:\\ 就行了?那试试呗。
改好了,报错啦!!!

VM512:35 WebSocket connection to 'wss://IP地址:端口号/websocket' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR
很明显 SSL 协议错误,说明就是证书问题了。记着,这时候我们一直拿的是 IP地址 + 端口号 这种方式连接 WebSocket 的,这根本就没有证书存在好么,况且生成环境你也要用 IP地址 + 端口号 这种方式连接 WebSocket 吗?肯定不行阿,要用域名方式连接 WebSocket 阿。
Nginx 配置域名支持 WSS
不用废话,直接在配置 HTTPS 域名位置加入如下配置:
location /websocket {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
接着拿域名再次连接试一下,不出意外会看 101 状态码:

这样就完成了,在 HTTPPS 下以域名方式连接 WebSocket ,可以开心的玩耍了。
稍微解释一下 Nginx 配置
Nginx 自从 1.3 版本就开始支持 WebSocket 了,并且可以为 WebSocket 应用程序做反向代理和负载均衡。
WebSocket 和 HTTP 协议不同,但是 WebSocket 中的握手和 HTTP 中的握手兼容,它使用 HTTP 中的 Upgrade 协议头将连接从 HTTP 升级到 WebSocket,当客户端发过来一个 Connection: Upgrade请求头时,Nginx 是不知道的,所以,当 Nginx 代理服务器拦截到一个客户端发来的 Upgrade 请求时,需要显式来设置Connection 、Upgrade 头信息,并使用 101(交换协议)返回响应,在客户端和代理服务器、后端服务器之间建立隧道来支持 WebSocket。
当然,还需要注意一下,WebSockets 仍然受到 Nginx 缺省为60秒的 proxy_read_timeout 的影响。这意味着,如果你有一个程序使用了 WebSockets,但又可能超过60秒不发送任何数据的话,那你要么需要增加超时时间,要么实现一个 ping 的消息以保持联系。使用 ping 的解决方法有额外的好处,可以发现连接是否被意外关闭。
更具体文档详见 Nginx 官方文档:http://nginx.org/en/docs/http/websocket.html
总结一下
这一篇文章主要了解一下 WebSocket 基本原理和一些使用用途,并解决在实际开发使用过程中遇到的坑,HTTPS 下使用 wss 协议的问题,以及配合 Nginx 使用域名方式建立连接,不使用 IP地址 + 端口号 连接 WebSocket,因为这种方式不够优雅。
下一篇,全站升级 HTTPS 之路,并没你想象的那么简单。
WebSocket 结合 Nginx 实现域名及 WSS 协议访问的更多相关文章
- WebSocket 结合 Nginx 实现域名及 WSS 协议访问-Nginx配置
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- 关于配置websocket,nginx转发https至wss问题
在本地测试通过的socket,再放到现在的有nginx代理之后发现会报:failed: Error in connection establishment: net::ERR_NAME_NOT_RES ...
- 微信小程序配置WSS协议
配置的是nginx转发,前提是你已经安装了nginx的软件并已经正常打开网页,安装好SSL协议,能打开https网页 下面是配置: 需要的话可以根据需求修改 server { listen 80; s ...
- vps被封逃逸_v2+cloudflare+websocket+tls+nginx
每逢重大节日,总有那么一大部分vps凉凉,以下为能正经正常使用vps,无奈之举,此法由于多层代理,夜间速度会有影响,白天感受不明显. 由于博客园内容审查,v2_ray 中间的 下划线为分隔符,相关链接 ...
- V2Ray+WebSocket+TLS+Nginx 配置及使用
v2ray 是一个模块化的代理工具,支持 VMess,Socks,HTTP,Shadowsocks 等等协议,并且附带很多高级功能,HTTP,TLS 等等. 关键词限制,全文 v2ray 中的 y 为 ...
- Nginx二级域名及多Server反向代理配置
Nginx强大的正则表达式支持,可以使server_name的配置变得很灵活,如果你要做多用户博客,那么每个用户拥有自己的二级域名也就很容易实现了. 注:nginx反向代理同一ip多个域名,给head ...
- nginx搭建http和rtmp协议的流媒体服务器
nginx搭建http和rtmp协议的流媒体服务器 时间:2013-09-23 23:52来源:佚名 作者:本站 举报 点击:232次 实验目的:让Nginx支持flv和mp4格式文件,同时支持Rtm ...
- 【转】Linux下nginx配置https协议访问的方法
一.配置nginx支持https协议访问,需要在编译安装nginx的时候添加相应的模块--with-http_ssl_module 查看nginx编译参数:/usr/local/nginx/sbin/ ...
- nginx二级域名配置
CentOs下nginx二级域名配置 域名配置文件 命名规则:XXX.域名信息.conf 配置文件路径:etc/nginx/conf.d/xxxx.conf 配置文件内容:server { liste ...
随机推荐
- OC中Foundation框架之NSString、NSMutableString
创建方式 )直接赋值 NSString *str =@"abc"; )创建对象 NSString *str2 = [[NSString alloc]init]; str2 =@&q ...
- MM们,你们为什么要找一个程序猿男票?
前言 免责声明:这篇文章关于什么?六一儿童节马上就要到了,作为一个前端攻城师,自我感觉效率还可以,老早已把任务搞完,页面布局和前端编码高效按时交付,呵呵.趁有时间,写写文章娱乐一下.MM们,请不要拿起 ...
- [刷题]算法竞赛入门经典(第2版) 4-4/UVa253 - Cube painting
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) #include<iostream> char str[15]; v ...
- mysql语句优化总结(一)
Sql语句优化和索引 1.Innerjoin和左连接,右连接,子查询 A. inner join内连接也叫等值连接是,left/rightjoin是外连接. SELECT A.id,A.nam ...
- linux c++爬虫(一)
int main(int argc, void *argv[]) { ]; ; char ch; ) { switch(ch) { case 'v': version(); break; case ' ...
- Jquery datatable 动态隐藏列(根据有无值)
一场景: 前端利用datatable初始化的时候会向后端调用数据,需求是 要动态的使某一列根据传回来的一个标志位是否有值来决定显示与否 这是当前传回值有活动优惠幅度的情况下 这是没有活动优惠的情况下 ...
- Mac OS 安装 Git 环境
1. 在mac的终端上,输入git会提示安装git软件,确认安装.安装完成后打开终端,使用git --version或者which git命令查看安装版本,有就是安装成功了. 2. 创建一个全局用户名 ...
- 看透SpringMVC源代码分析与实践 Markdown记录
kantouspringmvc 看透SpringMVC中文版电子书,使用Markdown语法记录学习<看透SpringMVC>的内容,方便自己整理知识,并在原作者写作的基础上添加自己的理解 ...
- 基于java:读写一个英文的txt文件,记录单词个数,并输出十个出现最多的单词及出现的个数;
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; class W ...
- 侯捷STL学习(一)
开始跟着<STL源码剖析>的作者侯捷真人视频,学习STL,了解STL背后的真实故事! 视频链接:侯捷STL 还有很大其他视频需要的留言 第一节:STL版本和重要资源 STL和标准库的区别 ...