1. 基础介绍:

Nginx1.3.13版本以上,开始支持WebSocket协议。

WebSocket协议是基于TCP的一种网络协议,实现浏览器和服务器全双工(full-duplex)通信 — 允许服务器主动发送信息给客户端。

WebSocket协议中,实现即时任务两大好处:1.Header很小(约2Bytes); 2.Server Push 服务器主动推送给浏览器。

WebSocket工作在HTTP的80和443端口并使用前缀ws://或者wss://进行协议标注,在建立连接时使用HTTP/1.1的101状态码进行协议切换,当前标准不支持两个客户端之间不借助HTTP直接建立Websocket连接。

2. Nginx配置WebSocket注意事项:

  1. 是否Nginx配置中,同时存在WebSocket 和 Http
  2. 默认情况下,proxy_read_timeout是60s;两次传输时长超过这个,就会断开连接! —解决— 代理服务器配置为定期发送WebSocket ping帧以重置超时

3. 客户端和服务端的报文

  1. <!--客户端的连接报文-->
  2. GET /webfin/websocket/ HTTP/1.1
  3. Host: localhost
  4. Upgrade: websocket
  5. Connection: Upgrade
  6. Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
  7. Origin: http://localhost:8080
  8. Sec-WebSocket-Version: 13
  1. <!--服务端的相应报文-->
  2. HTTP/1.1 101 Switching Protocols
  3. Upgrade: websocket
  4. Connection: Upgrade
  5. Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=

4. Nginx的配置参数

  1. # HTTP配置中,添加server关于websocket的配置
  2. # 为测试websocket添加
  3. # 1. 如果 $http_upgrade 不为 '' (空),则 $connection_upgrade 为 upgrade
  4. # 2. 如果 $http_upgrade 为 '' (空),则 $connection_upgrade 为 close
  5. map $http_upgrade $connection_upgrade {
  6. # default upgrade;
  7. # '' close;
  8. default keep-alive; #默认为keep-alive 可以支持 一般http请求
  9. 'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
  10. }
  11. # 表示的是 nginx负载均衡
  12. # 1. 两台服务器 (ip1:port1)和(ip2:port2)
  13. # 2. keepalive 1000 表示的是每个nginx进程中上游服务器保持的空闲连接,当空闲连接过多时,会关闭最少使用的空闲连接.当然,这不是限制连接总数的,可以想象成空闲连接池的大小.设置的值应该是上游服务器能够承受的
  14. upstream wsbackend{
  15. server ip1:port1;
  16. server ip2:port2;
  17. keepalive 1000;
  18. }
  19. # 添加测试websocket的代理
  20. # 表示的是监听的服务器的配置
  21. # 1. listen 20038 表示 nginx 监听的端口
  22. # 2. locations / 表示监听的路径(/表示所有路径,通用匹配,相当于default)
  23. # 3. proxt_http_version 1.1 表示反向代理发送的HTTP协议的版本是1.1,HTTP1.1支持长连接
  24. # 4. proxy_pass http://wsbackend; 表示反向代理的uri,这里可以使用负载均衡变量
  25. # 5. proxy_redirect off; 表示不要替换路径,其实这里如果是/则有没有都没关系,因为default也是将路径替换到proxy_pass的后边
  26. # 6. proxy_set_header Host $host; 表示传递时请求头不变, $host是nginx内置变量,表示的是当前的请求头,proxy_set_header表示设置请求头
  27. # 7. proxy_set_header X-Real-IP $remote_addr; 表示传递时来源的ip,还是现在的客户端的ip
  28. # 8. proxy_read_timeout 3600s; 表示两次请求之间的间隔超过 3600s 后才关闭这个连接,默认的60s。##自动关闭的元凶##
  29. # 9. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 表示X-Forwarded-For头不发生改变
  30. # 10. proxy_set_header Upgrade $http_upgrade; 表示设置Upgrade不变
  31. # 11. proxy_set_header Connection $connection_upgrade; 表示如果 $http_upgrade为upgrade,则请求为upgrade(websocket),如果不是,就关闭连接
  32. server {
  33. listen 12443;
  34. location /socketServer {
  35. # 反向代理到 EMQ 非加密 WebSocket ws
  36. # proxy_pass http://127.0.0.1:58080;
  37. proxy_pass http://wsbackend;
  38. # 反向代理保留客户端地址
  39. proxy_set_header X-Real_IP $remote_addr;
  40. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  41. # WebSocket 额外请求头
  42. proxy_http_version 1.1;
  43. proxy_set_header Upgrade $http_upgrade;
  44. proxy_set_header Connection $connection_upgrade;
  45. # WebSocket 设置断开连接的时间
  46. proxy_read_timeout 1800s;
  47. }
  48. }

4. Nginx配置模板:

  1. ######## Nginx的main(全局配置)文件
  2. #指定nginx运行的用户及用户组,默认为nobody
  3. #user nobody;
  4. #开启的线程数,一般跟逻辑CPU核数一致
  5. worker_processes 1;
  6. #定位全局错误日志文件,级别以notice显示,还有debug,info,warn,error,crit模式,debug输出最多,crir输出最少,根据实际环境而定
  7. #error_log logs/error.log;
  8. #error_log logs/error.log notice;
  9. #error_log logs/error.log info;
  10. #指定进程id的存储文件位置
  11. #pid logs/nginx.pid;
  12. #指定一个nginx进程打开的最多文件描述符数目,受系统进程的最大打开文件数量限制
  13. #worker_rlimit_nofile 65535
  14. events {
  15. #设置工作模式为epoll,除此之外还有select,poll,kqueue,rtsig和/dev/poll模式
  16. #use epoll;
  17. #定义每个进程的最大连接数,受系统进程的最大打开文件数量限制。
  18. worker_connections 1024;
  19. }
  20. #######Nginx的Http服务器配置,Gzip配置
  21. http {
  22. #主模块指令,实现对配置文件所包含的文件的设定,可以减少主配置文件的复杂度,DNS主配置文件中的zonerfc1912,acl基本上都是用include语句。
  23. include mime.types;
  24. #核心模块指令,智力默认设置为二进制流,也就是当文件类型未定义时使用这种方式
  25. default_type application/octet-stream;
  26. #下面代码为日志格式的设定,main为日志格式的名称,可自行设置,后面引用
  27. #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  28. # '$status $body_bytes_sent "$http_referer" '
  29. # '"$http_user_agent" "$http_x_forwarded_for"';
  30. #引用日志main
  31. #access_log logs/access.log main;
  32. #设置允许客户端请求的最大的单个文件字节数
  33. #client_max_body_size 20M;
  34. #指定来自客户端请求头的headebuffer大小
  35. #client_header_buffer_size 32k;
  36. #指定连接请求试图写入缓存文件的目录路径
  37. #client_body_temp_path /dev/shm/client_body_temp;
  38. #指定客户端请求中较大的消息头的缓存最大数量和大小,目前设置为4个32KB
  39. #large client_header_buffers 4 32k;
  40. client_max_body_size 10240m;
  41. keepalive_requests 10240;
  42. client_header_buffer_size 8k;
  43. open_file_cache max=102400 inactive=20s;
  44. open_file_cache_valid 30s;
  45. open_file_cache_min_uses 1;
  46. client_header_timeout 15;
  47. client_body_timeout 15;
  48. reset_timedout_connection on;
  49. send_timeout 15;
  50. #开启高效文件传输模式
  51. sendfile on;
  52. #开启防止网络阻塞
  53. #tcp_nopush on;
  54. #开启防止网络阻塞
  55. #tcp_nodelay on;
  56. #设置客户端连接保存活动的超时时间
  57. #keepalive_timeout 0;
  58. keepalive_timeout 65;
  59. #设置客户端请求读取超时时间
  60. #client_header_timeout 10;
  61. #设置客户端请求主体读取超时时间
  62. #client_body_timeout 10;
  63. #用于设置相应客户端的超时时间
  64. #send_timeout
  65. ####HttpGZip模块配置
  66. #httpGzip modules
  67. #开启gzip压缩
  68. #gzip on;
  69. #设置允许压缩的页面最小字节数
  70. #gzip_min_length 1k;
  71. #申请4个单位为16K的内存作为压缩结果流缓存
  72. #gzip_buffers 4 16k;
  73. #设置识别http协议的版本,默认为1.1
  74. #gzip_http_version 1.1;
  75. #指定gzip压缩比,1-9数字越小,压缩比越小,速度越快
  76. #gzip_comp_level 2;
  77. #指定压缩的类型
  78. #gzip_types text/plain application/x-javascript text/css application/xml;
  79. #让前端的缓存服务器进过gzip压缩的页面
  80. #gzip_vary on;
  81. #########Nginx的server虚拟主机配置
  82. server {
  83. #监听端口为 80
  84. listen 80;
  85. #设置主机域名
  86. server_name localhost;
  87. #设置访问的语言编码
  88. #charset koi8-r;
  89. #设置虚拟主机访问日志的存放路径及日志的格式为main
  90. #access_log logs/host.access.log main;
  91. #设置虚拟主机的基本信息
  92. location / {
  93. #设置虚拟主机的网站根目录
  94. root html;
  95. #设置虚拟主机默认访问的网页
  96. index index.html index.htm;
  97. }
  98. #error_page 404 /404.html;
  99. # redirect server error pages to the static page /50x.html
  100. error_page 500 502 503 504 /50x.html;
  101. location = /50x.html {
  102. root html;
  103. }
  104. # proxy the PHP scripts to Apache listening on 127.0.0.1:80
  105. #
  106. #location ~ \.php$ {
  107. # proxy_pass http://127.0.0.1;
  108. #}
  109. }