ThinkPHP 您现在的位置是:首页 > 开发笔记 > ThinkPHP

Nginx环境配置Websocket反向代理

来源:惠达浪原创 发布时间:2020-09-16 最后更新:2020-09-16 1468已围观

摘要最近在学习swoole,开发一个websocket服务,通常访问地址是带端口号的,而我希望它是一个友好的uri,经过一番折腾,终于弄明白了,特此记录。

最近在学习swoole的过程中,有这样一个需求:我的websocket地址是 ws://192.168.101.38:9527/ws,相信很多人都见过。我认为这样子开发还好,如果将来发布,或者更换服务器什么的,很是不友好,如果改成 ws://ws.myurl.com,不是更好记吗?于是我生成了一个子域名,用nginx做了一个代理,实现了这个想法。过程当然很是艰辛,不说了,没用,不知道有些博主为什么非要把试错的过程写下来。

直奔主题,我用的是宝塔面板,nginx服务。无论用什么方式,只要找到并打开配置文件就行。这里有两种情况:

  1. 单独的域名指向websocket服务。
    这种情况下,可以直接修改nginx.conf文件,不过大多数情况下,这个文件里都有这么一行:

    include /www/server/panel/vhost/nginx/*.conf;

    忽略路径,每台服务器可能不一样,不重要。重要的这句话表示主配置文件包含了所有的vhost下的子配置文件,因为每一个vhost就是一个虚拟站嘛。所以我的建议是,在vhost文件夹下,单独添加一个配置文件,专门用来配置websocket服务。

  2. 已有域名,额外添加websocket服务
    这时候,通常会用一个子目录的方式表达了,比如 ws://www.myurl.com/websocket 这个样子。那么,找到并打开这个域名对应的配置文件,宝塔面板里会容易一些。

无论上边两种情况的哪一种,其配置基本相同,无非是单独的配置文件,还是修改已经有文件而已,所以,重点来了:在server上层,也就是http内容里,配置如下内容

map $http_upgrade $connection_upgrade
{
  default upgrade;
  '' close;
}

这个不能写在server里边,否则会报错。很多网站没有提到这部分,导致服务不能用,原因就是三次握手,详细原因网上有的是,我懒得写了。这是第一个坑!这个配置的意思是,根据$http_upgrade变量的内容,设置$connection_upgrade的内容。$http_upgrade是nginx内置变量,百度这个东西就知道这种配置的详细说明了。然后,在server里添加如下内容:

location /ws
{
  proxy_pass http://127.0.0.1:9527;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection $connection_upgrade;
}

如果是第1种情况,你要在外边加上server{},把上边的内容放到大括号里边;如果是第2种情况,肯定是已经有server了,也有其它的location,只要和其它的location平级就行了。

第二个坑就是,很多网站在配置Connection时,压根就没用上边map的变量,而是直接写死为 "upgrade"!闹呢!那你还要在上边定义一个变量干毛啊!还有的不写map,只有下边这段,告诉你,也不行!我试过了。

解释一下重点吧,就是location后边的参数,如果是独立域名,直接解析根就行,那么就是 location /,我的例子是已有域名了,根已经给网站用了,所以多了个ws子目录,当然这个ws是自定义的,随便你怎么写。

下边第一行,proxy_pass后边,就是要指向的websocket地址,换句说话,直接就能访问的那个不友好的地址,可能是我写的这样,也可能后边还带子目录,以实际开发的地址为准。

解决了这两个坑,基本就没问题了,在客户端用js写一段代码测试一下吧:

const ws = new WebSocket('ws:// 
ws.onopen = evt => void console.log(ws.readyState)\
ws.onclose = evt => void console.log(ws.readyState)

没有报错,就是成功啦!收工!

很赞哦! (317)


上一篇: Trait和软删除

站点信息

  • 网站平台ThinkCMF 5.1.5
  • PHP版本:7.3.31
  • QQ交流群: 惠达浪技术交流