nginx是怎么支持websocket的

nginx配置

配置如下
 

server {
    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://websocket_upstream;
    }
}

服务器

一个简单服务器

客户端

使用telnet,例子如下

GET /websocket_upgrade HTTP/1.1
Host: localhost
Connection: Upgrade
Upgrade: websocket

HTTP/1.1 101 Switching Protocols
Server: BaseHTTP/0.6 Python/3.6.8
Date: Tue, 29 Oct 2019 14:59:42 GMT
Upgrade: websocket
Connection: Upgrade
Content-type: text/html
Connection: keep-alive

GET / HTTP/1.1
Host: localhost

HTTP/1.1 200 OK
Server: BaseHTTP/0.6 Python/3.6.8
Date: Tue, 29 Oct 2019 15:00:00 GMT
Content-type: text/html
Content-Length: 6
Connection: keep-alive

hello

 

nginx实现

/* 处理后端的响应 */
ngx_http_proxy_process_header() {
    /* 如果返回 101 */
    if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS) {
        u->keepalive = 0;
        
        /* 如果存在connection: upgrade */
        if (r->headers_in.upgrade) {
            u->upgrade = 1; /* !! nginx支持upgrade */
        }
    }
}

ngx_http_upstream_send_response()
{
	if(u->upgrade) {
		ngx_http_upstream_upgrade(r, u); /* 升级的核心 */
		return;	 
	}
}

ngx_http_upstream_upgrade() {
        /* 关键在与设置read/write处理函数 */
	u->read_event_handler = ngx_http_upstream_upgraded_read_upstream;                                                                            
	u->write_event_handler = ngx_http_upstream_upgraded_write_upstream;                                                                          
	r->read_event_handler = ngx_http_upstream_upgraded_read_downstream;                                                                          
	r->write_event_handler = ngx_http_upstream_upgraded_write_downstream;  
}

/*以上函数是对这个函数的包装,调用参数不同,就是从一个socket读,写入令一个socket,实际上可以splice 或者 socket map*/
ngx_http_upstream_process_upgraded(ngx_http_request_t *r, ngx_uint_t from_upstream, ngx_uint_t do_write)

nginx检查响应,如果响应码是101,并且头部有"connection: upgrade",那么就将连接升级,然后连接就是从一个socket往另一个socket搬运数据。

 

参考文献

websocket协议rfc翻译 https://juejin.im/post/5c6b7366e51d45016527d648

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值