在同一个路径下反代 Websocket 和 HTTP 服务
昨天重做了一个线上VPS的操作系统,结果忘记了备份 nginx
配置,
其中有一个配置还是比较棘手,这个服务是我的 Online Clipboard。
这个工具最初后端服务是基于 Swoole
实现的 Websocket
,后来
用户提了一个需求,希望在命令行下也能用,所以又在 Websocket
的
基础上增加了响应 HTTP
的功能,在代码里可以很清楚的看到这些。
然后最终的服务是依靠 Nginx
反代出来的。这里就有个问题,那就是Websocket
和 HTTP
都在一个路径下面。也就是说下面的两个路径
一个可以创建 Websocket
连接,一个可以直接通过 HTTP
访问 (其中username
和 password
是参数)
1 | wss://oc-server.to0l.cn/username/password |
尴尬的事情就是,之前我怎么配置的忘记了。这次重做系统丢掉配置后,
重新配置怎么也配不出来了,最后搜索到一个方案,就是通过报文头来
区分是 Websocket
还是 HTTP
,示例配置如下:
1 | map $http_upgrade $connection_upgrade { |
思路就是解析 /
的时候,尝试访问一个不存在的文件,既然不存在,
那么势必要内部访问 location @$http_upgrade
。
当来访访问是 Websocket
请求的时候, $http_upgrade
的值是websocket
,而来访访问是 HTTP
请求的时候,则是空值。
这样就把两个不同报文头的请求转发到两个不同的 location
中去了。
这样之前尴尬的问题就解决了。
配置好后,通过 curl https://oc-server.to0l.cn/public/public -d "content=test"
测试提交数据到剪切板,成功!
通过 curl https://oc-server.to0l.cn/public/public
访问最后
一条剪切板数据,成功!
浏览器访问 https://oc.to0l.cn
,分别输入剪切板名和密码后,可以
看到之前发的 test
信息,成功!