我有一个后端(NodeJS),它在某个端口(此示例中为2345)上进行监听。客户端应用程序是一个React应用程序。两者都利用socket.io
进行相互通信。两者都是容器化的。然后,使用“网络”标志在相同的网络上运行它们:
docker run -it --network=test1 --name serverapp server-app
docker run -it --network=test1 client-app
在客户端中,我有此代码(在服务器中,该代码是非常标准的,几乎是从socket.io页面复制粘贴的:]
const socket = io.connect('http://serverapp:2345');
socket.emit('getData');
socket.on('data', function(data) {
console.log('got data: ${data}');
})
[我怀疑问题出在http-server
程序包提供了客户端(React)应用程序,然后在浏览器上下文中,主机名无法理解,因此无法解析。当我进入浏览器控制台时,我看到以下错误:GEThttp://tbserver:2345/socket.io/?EIO=3&transport=polling&t=MzyGQLTnet :: ERR_NAME_NOT_RESOLVED
现在,如果我在客户端应用程序中将主机名serverapp
切换为localhost(浏览器可以理解,但不建议在docker中使用,因为它的解释有所不同),当尝试连接到服务器套接字时,我收到错误:获取http://localhost:2345/socket.io/?EIO=3&transport=polling&t=MzyFyAe net :: ERR_CONNECTION_REFUSED。
另一条信息是,我们当前构建React应用(使用npm run build
),然后我们使用以下Dockerfile构建并运行Docker容器:
FROM mhart/alpine-node
RUN npm install -g http-server
WORKDIR /app
COPY /app/build/. /app/.
EXPOSE 2974 2326 1337 2324 7000 8769 8000 2345
CMD ["http-server", "-p", "8000"]`
(因此,在构建容器时不会进行React应用的构建;我们宁愿依赖一次预构建)
[不确定我在这里缺少什么以及是否与http-server
有关,但是在此之前,我设法使用相同的Docker网络在2个NodeJS应用程序之间获得了一个完全正常的socket.io
连接,因此不应该是代码问题。
您的浏览器需要知道如何解析SocketIO服务器地址。您可以公开2345
的端口serverapp
,并将主机的端口2345
绑定到2345
]的端口[C0
serverapp
这样您就可以在客户端代码中使用本地主机
docker run -it --network=test1 -p 2345:2345 --name serverapp server-app
也从客户端Dockerfile中删除const socket = io.connect('http://localhost:2345');