Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

websocket不能正常工作 #502

Open
snowie2000 opened this issue Apr 13, 2020 · 30 comments
Open

websocket不能正常工作 #502

snowie2000 opened this issue Apr 13, 2020 · 30 comments
Labels
bug Something isn't working

Comments

@snowie2000
Copy link
Contributor

使用域名解析功能连接内网hassbian(homeassistant),该服务主要使用websocket作为通信手段。

期望结果:
网页正常展示

实际情况:
可以进入登录页并认证,但最终界面无法展示。
开发者工具显示websocket能建立连接,但数据只发不收,不能获得服务端的返回
ws
上图是正常通信的websocket报文。
使用nps时只有第一行,后面的没有。

完全相同的配置下frp无此问题。

@snowie2000 snowie2000 added the bug Something isn't working label Apr 13, 2020
@snowie2000
Copy link
Contributor Author

snowie2000 commented Apr 13, 2020

hass服务端出现错误日志:

Log Details (WARNING)
Logger: homeassistant.components.websocket_api.http.connection.1728204624
Source: components/websocket_api/http.py:217
Integration: websocket_api (documentation, issues)
First occurred: 4:36:52 PM (1 occurrences)
Last logged: 4:36:52 PM

Disconnected: Did not receive auth message within 10 seconds

@ffdfgdfg
Copy link
Collaborator

#474 websocket 域名解析模式暂时还不支持

@snowie2000
Copy link
Contributor Author

snowie2000 commented Apr 14, 2020

我读了一下http.go代码,发现其中存在的问题非常多,你是自己实现了一个简单的反向代理,但为了实现flow控制代码逻辑过于简单,对于例如response都是先dump再write,如果客户端发送一个很大的文件,将对服务端产生巨大压力,并且由于需要完全接受,所以FTTB就会很长。

另外在for循环中bufio.NewReader的行为也不可接受,创建了一大堆临时对象却不释放,并且bufio本身会从io.Reader中缓存数据,这也就是

//What happened ,Why one character less???
的问题所在。

@cnlh
Copy link
Collaborator

cnlh commented Apr 14, 2020

我读了一下http.go代码,发现其中存在的问题非常多,你是自己实现了一个简单的反向代理,但为了实现flow控制代码逻辑过于简单,对于例如response都是先dump再write,如果客户端发送一个很大的文件,将对服务端产生巨大压力,并且由于需要完全接受,所以FTTB就会很长。

另外在for循环中bufio.NewReader的行为也不可接受,创建了一大堆临时对象却不释放,并且bufio本身会从io.Reader中缓存数据,这也就是

//What happened ,Why one character less???

的问题所在。
对于你说的【response都是先dump再write】这个只是针对需要缓存的情况,正常情况不会dump,bufio.NewReader确实是个问题。
代码刚开始写的比较粗糙,确实有很多不足之处,也欢迎大家pr修改。

@snowie2000
Copy link
Contributor Author

不光是bufio有重复创建的情况,LenConn也是在不停的重复创建,目的只是为了统计流量。
现有的http代理架构确实存在比较大的问题,不建议hijack以后自己处理。

建议可以从httputil.ReverseProxy上进行继承修改,很容易就能实现websocket的支持和流量统计

@snowie2000
Copy link
Contributor Author

经过基于reverseproxy的修改,nps可以正常连上websocket并进行交互。nps现有的架构确实存在问题。
ws1
服务端日志:正确创建了ws链接
ws2
ws正确发送报文。

由于改动很大,并且不符合nps现有的流量统计,也不能支持nps的auth,所以pr暂时就不发了,发了也不可能合并。只是证实了基于reverseproxy修改的可行性。

@ffdfgdfg
Copy link
Collaborator

是的,计划排在后面,现在主要处理些小改动

@LogicJake
Copy link

请问这个问题解决了吗,我在使用jupyter notebook时发现依旧存在该问题无法正常使用

@icanc0
Copy link

icanc0 commented Apr 11, 2021

同上,找不到另一个更好用的内网穿透工具,可惜nps不支持ws

@snowie2000
Copy link
Contributor Author

同上,找不到另一个更好用的内网穿透工具,可惜nps不支持ws

frp比这个稳定太多了,nps只是界面比较好看而已……

@icanc0
Copy link

icanc0 commented Apr 13, 2021

看了看frp的doc,frp的界面没法比呀

@snowie2000
Copy link
Contributor Author

Frp可以说没有界面,都是配置文件设置的。你想要稳定就用它,想要界面好看只能用nps

@anylines
Copy link

这个问题我也是,frp正常。本来打算全部切nps无奈,这个网页打不开。

@icanc0
Copy link

icanc0 commented Jun 28, 2021

Frp可以说没有界面,都是配置文件设置的。你想要稳定就用它,想要界面好看只能用nps

我用nps就是因为有界面,我在外面的时候可以直接通过网页端修改,太方便了。

本来想自己把cache和keepalive加进去,可惜我水平有限,没写过这么大的project。

@snowie2000
Copy link
Contributor Author

Frp可以说没有界面,都是配置文件设置的。你想要稳定就用它,想要界面好看只能用nps

我用nps就是因为有界面,我在外面的时候可以直接通过网页端修改,太方便了。

本来想自己把cache和keepalive加进去,可惜我水平有限,没写过这么大的project。

那么有几个办法

  • 把tcp连接当http用,ws就不是问题了,但是端口就没法复用了。
  • 放弃ws,乖乖http
  • 自己实现ws支持
  • 找我以前发的pr改改,直接merge肯定不可能了

@befantasy
Copy link

现在支持了吗???
最近遇到类似的问题,折腾了半天用TCP隧道解决了。。。搜了搜果然是不支持websocket。。。。

@icanc0
Copy link

icanc0 commented Mar 7, 2022

v2.0 应该可以支持了吧?

@YYCoder
Copy link

YYCoder commented Mar 27, 2022

现在支持了吗??? 最近遇到类似的问题,折腾了半天用TCP隧道解决了。。。搜了搜果然是不支持websocket。。。。

麻烦问下,怎么用 tcp 隧道解决的?我试了半天还是不行

@befantasy
Copy link

现在支持了吗??? 最近遇到类似的问题,折腾了半天用TCP隧道解决了。。。搜了搜果然是不支持websocket。。。。

麻烦问下,怎么用 tcp 隧道解决的?我试了半天还是不行

homeassistant?直接新增tcp隧道,映射内网目标服务器8123端口啊,然后公网的服务端用nginx反代

@icanc0
Copy link

icanc0 commented Mar 27, 2022

看到了一个dev-2.0的branch,感觉要有websocket支持了。

@YYCoder
Copy link

YYCoder commented Mar 27, 2022

不是 homeassistant,是我自己搭的一个内网 http 服务,里面依赖了 ws。我建了 tcp 隧道,但是没有配置域名解析的话,http 服务就会用不了,不知道为啥

@befantasy
Copy link

不是 homeassistant,是我自己搭的一个内网 http 服务,里面依赖了 ws。我建了 tcp 隧道,但是没有配置域名解析的话,http 服务就会用不了,不知道为啥
NPS服务端所在的服务器80或443端口上,配置一个Nginx Proxy Manager之类的做反向代理。

@YYCoder
Copy link

YYCoder commented Mar 27, 2022

不是 homeassistant,是我自己搭的一个内网 http 服务,里面依赖了 ws。我建了 tcp 隧道,但是没有配置域名解析的话,http 服务就会用不了,不知道为啥
NPS服务端所在的服务器80或443端口上,配置一个Nginx Proxy Manager之类的做反向代理。

我配置了,但是不知道哪里的配置有问题,现象是报了 404,如下:
image
我怀疑是不是我的 nginx 配置的 proxy_pass 的端口有问题,请问这个端口应该配置成 nps 配置项里的 bridge_port 还是http_proxy_port?
image

@befantasy
Copy link

不是 homeassistant,是我自己搭的一个内网 http 服务,里面依赖了 ws。我建了 tcp 隧道,但是没有配置域名解析的话,http 服务就会用不了,不知道为啥
NPS服务端所在的服务器80或443端口上,配置一个Nginx Proxy Manager之类的做反向代理。

我配置了,但是不知道哪里的配置有问题,现象是报了 404,如下: image 我怀疑是不是我的 nginx 配置的 proxy_pass 的端口有问题,请问这个端口应该配置成 nps 配置项里的 bridge_port 还是http_proxy_port? image

都不是,这个是要配置成你新建的TCP隧道的“服务端端口”(local port)

@YYCoder
Copy link

YYCoder commented Mar 27, 2022

不是 homeassistant,是我自己搭的一个内网 http 服务,里面依赖了 ws。我建了 tcp 隧道,但是没有配置域名解析的话,http 服务就会用不了,不知道为啥
NPS服务端所在的服务器80或443端口上,配置一个Nginx Proxy Manager之类的做反向代理。

我配置了,但是不知道哪里的配置有问题,现象是报了 404,如下: image 我怀疑是不是我的 nginx 配置的 proxy_pass 的端口有问题,请问这个端口应该配置成 nps 配置项里的 bridge_port 还是http_proxy_port? image

都不是,这个是要配置成你新建的TCP隧道的“服务端端口”(local port)

大佬牛逼!!!http 请求可以了,但是为什么 wss 还是不行,我看 nginx 日志是报这个,需要 nginx 做额外配置吗?
image

@icanc0
Copy link

icanc0 commented Mar 27, 2022

不是 homeassistant,是我自己搭的一个内网 http 服务,里面依赖了 ws。我建了 tcp 隧道,但是没有配置域名解析的话,http 服务就会用不了,不知道为啥

NPS服务端所在的服务器80或443端口上,配置一个Nginx Proxy Manager之类的做反向代理。

我配置了,但是不知道哪里的配置有问题,现象是报了 404,如下: image 我怀疑是不是我的 nginx 配置的 proxy_pass 的端口有问题,请问这个端口应该配置成 nps 配置项里的 bridge_port 还是http_proxy_port? image

都不是,这个是要配置成你新建的TCP隧道的“服务端端口”(local port)

大佬牛逼!!!http 请求可以了,但是为什么 wss 还是不行,我看 nginx 日志是报这个,需要 nginx 做额外配置吗?

image

我看你没加http upgrade,没有http upgrade的话ws工作不了

@YYCoder
Copy link

YYCoder commented Mar 27, 2022

不是 homeassistant,是我自己搭的一个内网 http 服务,里面依赖了 ws。我建了 tcp 隧道,但是没有配置域名解析的话,http 服务就会用不了,不知道为啥

NPS服务端所在的服务器80或443端口上,配置一个Nginx Proxy Manager之类的做反向代理。

我配置了,但是不知道哪里的配置有问题,现象是报了 404,如下: image 我怀疑是不是我的 nginx 配置的 proxy_pass 的端口有问题,请问这个端口应该配置成 nps 配置项里的 bridge_port 还是http_proxy_port? image

都不是,这个是要配置成你新建的TCP隧道的“服务端端口”(local port)

大佬牛逼!!!http 请求可以了,但是为什么 wss 还是不行,我看 nginx 日志是报这个,需要 nginx 做额外配置吗?
image

我看你没加http upgrade,没有http upgrade的话ws工作不了

有道理,我 google 一下 nginx 怎么配置 ws 代理,感谢大佬~

BTW,感觉 nps 的配置好难,好多端口要配置,自己也理解不清楚什么时候要用哪个,不知道有没有简单容易理解的做法~

@icanc0
Copy link

icanc0 commented Mar 27, 2022

nps算简单的了,但是nps dashboard和doc上的解释的不是很清楚,nps又涉及到客户端和服务端,对networking不怎么了解的人不是很友好

@YYCoder
Copy link

YYCoder commented Mar 27, 2022

nps算简单的了,但是nps dashboard和doc上的解释的不是很清楚,nps又涉及到客户端和服务端,对networking不怎么了解的人不是很友好

确实,感觉我得补一补网络方面的知识了,感谢各位大佬帮助😁。

@zuilintan
Copy link

zuilintan commented Feb 29, 2024

我在用Nginx进行反向代理,遇到了类似的问题,
场景如下:
公网服务器部署NPS。家中内网电脑开启Stable Diffusion,并开启NPC,
外网通过域名访问Stable Diffusion,可以打开网页,但提示连接错误,且无法出图。
而通过域名:端口,或IP:端口访问却一切正常。

至此可确定必然为Nginx的锅。

这时打开浏览器的检查,看到控制台有如下输出:
WebSocket connection to 'ws://xxx.xxx.com/queue/join' failed
显然,WebSocket未能被Nginx正常转发。
带着这个问题点去问ChatGPT,很容易就找到了对策:

server {
    listen 80;
    server_name xxx.xxx.com;

    location / {
        proxy_pass http://localhost:端口;
        # 重点在此后的三行配置
        # 这个指令确保使用HTTP/1.1通信,WebSocket需要HTTP/1.1来进行升级请求。
        proxy_http_version 1.1;
        # 这个指令将客户端请求的Upgrade头信息传递给后端服务器。WebSocket协议升级请求需要这个头信息。
        proxy_set_header Upgrade $http_upgrade;
        # 这个指令用于修改Connection头信息,告诉后端服务器客户端想要升级连接。确保将proxy_pass后面的URL替换为你的Stable Diffusion服务的实际内网IP地址和端口。
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

修改后,reload一下nginx即可

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

9 participants