【问题标题】:CloudFoundry websocket failed: Establishing a tunnel via proxy server failedCloudFoundry websocket失败:通过代理服务器建立隧道失败
【发布时间】:2016-11-19 23:06:59
【问题描述】:

注意:我没有使用 Pivotal CF。

我在 CloudFoundry 上部署了一个 java 应用程序。我正在使用嵌入式 Jetty 来托管我的 Jersey REST API。默认情况下,Cloud Foundry 在端口 8080 上公开此 API。

我的应用程序还需要一些 websocket 将数据流式传输到浏览器。我为此使用 Java-WebSocket (https://github.com/TooTallNate/Java-WebSocket)。在我的本地机器上,我使用端口 8887 进行 websocket 连接。一切正常。

在 CloudFoundry 上部署后,我可以访问我的 REST API,但不能访问我的 websocket。网上搜索了一下,发现websocket连接只允许在4443端口(@98​​7654322@)

我更改了我的服务器端以反映这一点

import org.java_websocket.server.WebSocketServer;
public class MyWebSocket extends WebSocketServer {
    public MyWebSocket() throws UnknownHostException {
        super(new InetSocketAddress(4443));
    }

    @Override
    public void onOpen(org.java_websocket.WebSocket websocket, ClientHandshake handshake) {
      // Handle this
      }
}

在我的客户端,我正在使用以下方式连接 websocket

wss://my_cf_app.com:4443/

但我得到以下异常。

到“wss://my_cf_app.com:4443/”的 WebSocket 连接失败: 通过代理服务器建立隧道失败

我还尝试使用 CF 的“PORT”环境变量连接服务器端的 websocket,但在 Java-WebSocket 中出现“地址已在使用”错误。

我尝试了很多不同的方法,但我无法弄清楚这一点。任何帮助都会很棒。

【问题讨论】:

  • 你为什么不使用嵌入式码头内置的 WebSocket 服务器支持?
  • 我的 REST API 在泽西岛部署在 Jetty 上。我试图让 websocket 在 Jersey 上运行,但我失败了。这就是我搬到另一个图书馆的原因。假设我在 Jetty 上实现了 websockts,它可以在 CF 上运行吗?我的意思是 Jersey 上的 REST API 和 Jetty 上的套接字?我可以同时使用 8080 端口的 CF 服务吗?
  • 是的,这就是 websocket 的重点,它只是一个升级的 HTTP 连接,使用相同的服务器、相同的连接器、相同的端口等......

标签: java embedded-jetty cloud-foundry


【解决方案1】:

在 CloudFoundry 上部署后,我可以访问我的 REST API,但不能访问我的 websocket。网上搜索了一下,发现websocket连接只允许在4443端口(@98​​7654321@)

端口 4443 特定于 Pivotal Web 服务(以及在 AWS 上运行的一些 CF 安装)。大多数 PCF 安装没有单独的 WSS 端口,而只是使用 443 和 HTTPS 流量。最终使用的端口取决于 CF 安装前使用的负载均衡器及其支持的内容。

您将永远让您的应用程序侦听端口 4443。端口 4443 是负载均衡器侦听的外部流量端口。此流量将被定向到分配给您的应用程序的端口,即 $PORT(环境变量)。

我还尝试使用 CF 的“PORT”环境变量连接服务器端的 websocket,但在 Java-WebSocket 中出现“地址已在使用”错误。

这是正确的行为,即您应该监听通过 $PORT 环境变量分配的端口。错误告诉您的是,某些东西已经在此端口上侦听,并且您不能让两个东西在同一个端口上侦听。

目前每个应用程序只有 一个 端口可用(将来可能会更改)。目前,如果您有两个单独的应用程序在两个单独的端口上侦听,那么您需要将它们作为两个单独的应用程序推送到 CF。

要使它们在最终用户看来像一个应用程序,您可以做的是将每个应用程序映射到特定路径。请参阅 cf push--route-path 参数或 cf create-route 的文档。

https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#create-route

【讨论】:

  • 嗯,所以你说只有一个端口暴露给 CF 应用程序,这是在 env 变量“PORT”中指定的。对于更多端口,我们需要单独部署 :( ?
  • 是的,目前外部流量只发送到应用容器中的一个端口。您可以侦听多个端口,它们只是无法访问,也不会有流量流向它们。除非您要在您的应用程序中拥有充当代理的东西。例如:proc-1 监听 5000,proc-2 监听端口 5001。没有外部流量会到达这些端口。现在,如果 proc-3 监听 $PORT 并将流量转发到 proc-1 和 proc-2 端口,那么外部流量将达到 5000 和 5001,但您需要进行设置,并且只有两个应用程序更容易。
  • 知道了。感谢您的信息。顺便说一句,我的应用程序非常简单(实际上是一个演示),我加载页面....单击一个按钮,该按钮启动套接字并使用页面上的流。然后如果用户按下停止,我只是通知服务器。也许,一旦页面加载完毕,
  • 我可以断开 Jetty 与 8080 端口的连接,并将 websocket 绑定到该端口并推送数据。推送数据后,断开 websocket 并再次绑定。我不确定这是否可能,是否可行。
猜你喜欢
  • 2017-10-08
  • 2019-01-16
  • 2018-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-10
  • 1970-01-01
相关资源
最近更新 更多