Java Spring MVC WebSocket 应用程序仅适用于本地应用程序服务器,但不适用于 openshift 主机

Posted

技术标签:

【中文标题】Java Spring MVC WebSocket 应用程序仅适用于本地应用程序服务器,但不适用于 openshift 主机【英文标题】:Java Spring MVC WebSocket application works on local application server only but not on openshift host 【发布时间】:2016-05-17 16:14:30 【问题描述】:

我尝试使用 Spring MVC 进行简单的 websocket 聊天。 源代码可在我的存储库中找到GitHub 它由以下部分组成: 欢迎查看页面 index.jsp 包含用于输入用户昵称和密码并将其绑定到新用户实例的表单。

用户实例被传递给 Spring MVC 控制器 MainController.java。 Controller 创建链接到 chat.jsp 的新 ModelAndView 并将 User 实例传递给它,以便在标题和聊天窗口中显示用户的昵称。 chat.jsp 包含提供与 Chat.java 中的 websocket 端点的连接的 js 代码。它还将用户的昵称传递给端点以将其存储在其字符串字段中。 当我在本地 Tomcat 8 上尝试时,一切正常,正如预期的那样。

这是 websocket 端点连接的请求和响应。

但是当我在 OpenShift 的 Tomcat 7 远程主机上尝试它时,它不起作用。 以下是截图:

如您所见,用户的昵称没有显示在标题中,也没有通过请求 URL 传递到端点。 似乎连 User 实例都没有从 Spring MVC 控制器传递到 chat.jsp 视图页面。 有人可以解释一下我做错了什么吗?

【问题讨论】:

你的本地应用服务器是什么? 正如我提到的,它是 Tomcat 8。 【参考方案1】:

我发现有两个问题:

    Ws 和 wss 端口 - use ports 8000 or 8443 用于 OpenShift 上的 Web 套接字连接。我建议修改你的chat.jsp

    Chat.initialize = function () 
      if (window.location.protocol == 'http:') 
        Chat.connect('ws://' + window.location.host + ':8000/websocket/chat/$user.nickname');
       else 
        Chat.connect('wss://' + window.location.host + ':8443/websocket/chat/$user.nickname');
      
    ;
    

    Tomcat 服务器版本。您可以使用 this quick-start 在 OpenShift Online 上运行 Tomcat 8。然而,当我尝试使用快速入门时,我遇到了一些麻烦,所以我改变了一些东西并创建了一个 PR;在合并之前,您可以从here 获取对我有用的版本。为了在小型 DIY 设备上部署 Tomcat 8,您可以使用以下命令:rhc app create tomcat8 diy --from-code https://github.com/jiri-fiala/openshift-tomcat8-quickstart。将 tomcat8 替换为您想要的应用名称。请注意,下载和编译 Tomcat 8 需要几分钟时间。

在 OpenShift 上运行 Tomcat 8 后,我使用 Tomcat 的 Web 界面将您的代码部署为 ROOT.war(我使用 mvn package 在本地创建了一个包)。测试聊天应用似乎还不错。

当然,这不是一个非常理想的部署; Web 应用程序以这种方式部署到数据目录。 OpenShift Online 目前不提供 Tomcat 8 插件,您可以在其中将代码推送到 repo 并自动构建和部署您的 Web 应用程序。

【讨论】:

感谢您的建议。但是我不想在 OpenShift 上运行 Tomcat 8,我只想修改我的代码以使其在 Tomcat 7 上运行。但是,我按照您的建议在 websocket 端点连接请求中添加了端口号。现在我的chat.jsp 已连接到端点。但连接在建立后立即关闭。 有没有其他方法可以在请求中添加端口号?因为现在应用程序无法在 localhost 上运行,因为 websocket 连接请求现在看起来像 ws://lockalhost:8080:8000/websocket... 。 我建议在本地在 Tomcat 7 上开发代码,然后将其部署在远程 Tomcat 7 上。重新使用硬编码的连接字符串 - 您可以检查您正在运行的环境,例如基于environment variables that are on OpenShift & 不在本地使用,或者将连接字符串完全存储在环境变量中,您可以在本地使用set on OpenShift,独立于代码。【参考方案2】:

解决了一个问题。现在用户昵称显示在视图标题中,并且它也通过连接请求传递给 websocket 端点。 我刚刚在 chat.jsp 中添加了一行 <%@ page isELIgnored="false" %> 以使表达式语言工作。出于某种原因,如果您使用 Tomacat 7,则有必要。 所以现在在将端口号添加到 websocket 端点连接请求之后,我得到了这个: 但聊天仍然无法正常工作,因为连接在建立后立即关闭。

【讨论】:

以上是关于Java Spring MVC WebSocket 应用程序仅适用于本地应用程序服务器,但不适用于 openshift 主机的主要内容,如果未能解决你的问题,请参考以下文章

是否可以与 Spring MVC 一起创建 WebSocket 应用程序

如何在Spring中配置Websocket

在基于 Spring MVC 的服务器上实现 WebSocket

如何在 websocket onopen 事件中访问 spring mvc 属性值?

spring mvc 学习笔记---前言

JBoss 上带有 SockJS 的 Spring-MVC Websocket:如果没有 IO 事件,无法从 HTTP/1.1 升级