当前位置: 首页 > 知识库问答 >
问题:

如何将spring数据rest与spring websocket混合到单个实现中

颛孙和颂
2023-03-14

我想将状态同步到对特定实体更改感兴趣的所有客户端。所以我想实现以下目标:

  • 在实体上公开CRUD API(通过HTTP/RESTwebsockets

所以从技术上讲,我对将spring数据rest与spring websocket实现相结合的想法很感兴趣,以实现类似spring数据websocket的功能。

我想到了两个解决方案,事实上都是:

  • spring data rest通过rest/HTTP API
  • websocket控制器(用于对实体的修改调用)

websocket控制器如下所示:

@Controller
public class EntityAWebSocketController {
      @MessageMapping("/EntityA/update")
      @SendTo("/topic/EntityA/update")
      public EntityA update(EntityA entityA) throws Exception {
           // persist,....
           return entityA;
     }
}

场景1:从REST/HTTP API调用的Websocket API

规则:

  • 客户端请求总是REST/httpapi
  • 所有操作的响应都是REST/httpapi
  • 此外,对于修改操作,websocket消息也会出现

从技术上讲,可以通过以下方式实现:

  • 从spring rest数据事件调用websocket控制器(即在AfterCreateEventAfterSaveEventAfterLinkSaveEventAfterDeleteEvent

不过,这个解决方案对我来说似乎很恶心,因为我需要:

  1. 客户端A--HTTP请求--

场景2:Websocket API独立于REST API

规则:

  • 客户端请求是仅用于非修改操作的REST/HTTP API
  • 响应是REST/httpapi,仅用于非修改操作
  • 客户端为所有修改操作发送websocket消息
  • websocket消息仅发送给客户端进行所有修改操作

好吧,如果没有其他想法出现,我会选择后面的,但仍然,如果我可以以某种方式生成C(R)UD方法,通过webockets公开,就像spring-data-webockets一样,并且只处理我实现中的路由,那就太好了。

因为我觉得我必须手动公开(通过*WebSocketControllers)我所有实体的CUD方法。我可能太懒了。

思想?

共有2个答案

贺运良
2023-03-14

同样的架构已经困扰了我一段时间,如果我想提及它的所有缺点和优点,那将是一个很长的故事,所以让我开始讨论它的实现。

第二个场景是有效的,但正如您所提到的,在同一个websocket会话上执行crud操作更好。这将消除每次请求时HTTP握手的需要,并减少html" target="_blank">消息的正文大小,因此您将有更好的延迟。同时,您已经有了一个到服务器的持久连接,那么为什么不好好利用它呢?

我搜索了一段时间,从你的问题开始6年后,我仍然找不到任何websocket协议可以实现这一点,所以我决定自己解决这个问题,因为我需要它来完成另一个虚拟项目。

这种协议的另一个优点可能是它不需要对您已经编写的控制器进行太多更改。因此,它应该能够支持Spring框架(例如)注释并从中创建websocketendpoint。在另一个框架(例如Spring)中实现此类协议的困难之处在于,由于创建ServletRequest和ServletACK并将它们转换为您自己的websocket协议并不是一件好事,因此您会失去一些优势。例如,您在应用程序中编写的任何超文本传输协议过滤器到那一刻都将毫无意义,因为通过这些过滤器传递您的websocket消息并不容易。

关于协议本身:我决定所有内容都通过json格式传递,每个请求都有一个唯一的id,这样我们就可以将客户端的回调映射到请求id。当然,还有一个过滤器链可以向其中添加过滤器。

另一个很难解决的问题是Spring Security性,因为它在某些情况下也像http过滤器一样工作。在我自己的库中,我终于可以处理像@PreAuthorize这样的注释,但如果您在HTTP安全配置中使用antMatchers,这将是一个问题。

因此,创建websocket适配器来调用http控制器将有许多缺点。

你可以在这里查看这个项目:在Websocket上Rest。它是为Spring Boot编写的。

关项明
2023-03-14

场景2在最后一步中讨论了单个客户机。但我认为你的要求是一个主题,因为你需要多个客户。如果我想为您所述的需求填写2,那么您可能需要维护一个客户机列表,并实现您自己的队列,或者使用ForkJoinPool向所有在WebSocket上监听的客户机发送消息。话虽如此,这里的主题肯定更优雅,但总的来说,不同的界面看起来太复杂了

对于从客户端到服务器的所有消息,只需使用简单的有线协议并使用集合来参数化,它可能是RParam1......

在服务器上,需要一个控制器将这些映射到不同的请求(和操作)。不知怎么的,看起来不像是太多的工作。希望这有帮助。

 类似资料:
  • ... 而这个RestResource dao 向API/公司发送请求: 我尝试创建以下bean,但它似乎从来没有做任何事情: 即使它确实有效,它将如何帮助我使用正确的http代码和可理解的json响应开发更好的错误响应? 如此困惑 使用1.3.2.发布

  • 我有一个实体说 当调用以下url时,我可以在多个字段上搜索/筛选数据 在这里我有两个选择: 在Lucene中索引 索引 我对这两种选择都没意见。问题是如何将它与JPA集成,以便以下url仍然有效,只是这次查询是从Hibernate搜索索引构建并由JPA执行的:

  • Spring数据REST(尤其是Spring HATEOAS)将RESTful ID(即URI)与实体ID解耦,在保存新对象时,我很难将它们链接起来。有关此解耦的有趣讨论,请参见https://github.com/SpringSource/spring-data-rest/issues/13. 假设一个客户端应用程序想要创建一个新的票证资源和一个关联的票证类别资源。我想针对远程Spring数据R

  • 正如标题所说,当我将spring数据rest存储库添加到现有的spring数据rest webmvc项目中时,我开始在项目运行中出错。 我试图使用@ConvertBy(MyConverter.class)在实体中遵循此链接进行嵌入ID转换。然而,仅仅添加jar就会导致以下错误和大量o. s. c. i. s. PathMatchingResourcePatterResolver日志。

  • 当我尝试使用以下命令将数据发布到我的REST API(使用Spring DATA JPA REST创建)时: 我得到这个错误:

  • 大家好,我正在学习如何使用MySQL和Node JS,我正在尝试找到一个混合两个表的查询。如果我得到一个表“users”,其中有列“userid”、“userimage”,另一个表“comments”,其中有列“commentID”、“comment”、“commentuserid”、“threadid”。你知道我是否可以添加用户的图片谁评论在这个查询的结果请?