与多个Chrome Docker容器进行Websocket通信
我有一个Chrome容器(使用此Dockerfile部署),可应要求从App容器渲染页面。
基本流程是:
- 应用程序向Chrome发送了一个http请求,并作为响应接收了要使用的websocket网址(例如
ws://chrome.example.com:9222/devtools/browser/13400ef6-648b-4618-8e4c-b5c73db2a122
) - 然后,应用程序使用该websocket网址与Chrome进一步通信,并接收呈现的页面。我正在使用puppeteer库通过以下方式连接到Chrome实例并与之通信
puppeteer.connect({ browserWSEndpoint: webSocketUrl })
:
对于单个Chrome容器,效果很好。
但我正在尝试扩大规模,以在Docker群中拥有多个Chrome容器。
我认为问题在于,App接收到的websocket
URL特定于在该特定Chrome容器中运行的实例,因此,当App使用它(并且现在有多个Chrome容器)时,来自App的websocket请求将不一定会路由到正确的Chrome容器。
处理此问题的最佳方法是什么?
回答:
您的基本设计正确,但是您遇到的问题是会话“粘性”。但是,与其尝试将后续请求重新路由回适当的计算机,不如寻找一种避免“预”请求的方法。
最好的方法是让您的Chrome泊坞窗图片位于所有http“升级”请求的中间人。此http动作是所有WebSocket连接在更改协议(包括puppeteer库,它只是一个WebSocket客户端)之前发出的内容。这样做还可以避免进行预连接呼叫,因为到Chrome的代理将发生在升级过程中,而不是公开要使用的URL。这是使用http-
proxy模块执行此操作的一个非常基本的示例:
const http = require('http');const httpProxy = require('http-proxy');
const proxy = new httpProxy.createProxyServer();
http
.createServer()
.on('upgrade', async(req, socket, head) => {
const browser = await puppeteer.launch();
const target = browser.wsEndpoint();
proxyy.ws(req, socket, head, { target })
})
.listen(3000);
这种方法还有其他好处:您可以限制诸如并发之类的内容,甚至可以注入脚本以在以后运行。这些虽然需要更多和准备,但总体思路仍然相同。这也使负载平衡变得微不足道,因为不需要使路由变得固定。
如果这是您感兴趣的事情,那么您可以在无浏览器的存储库中为您完成所有工作。它甚至允许诸如并发限制,会话时间限制之类的功能,并包括功能丰富的IDE。您可以在此处找到有关该项目的更多文档。
以上是 与多个Chrome Docker容器进行Websocket通信 的全部内容, 来源链接: utcz.com/qa/414147.html