Java 使用 Springboot 预定 websocket 推送

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37307697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:11:20  来源:igfitidea点击:

Scheduled websocket push with Springboot

javaspringwebsocketspring-bootpush-notification

提问by Konstantine

I want to create a simple news feed feature on the front end that will automatically update through websocket push notifications.

我想在前端创建一个简单的新闻提要功能,该功能将通过 websocket 推送通知自动更新。

The technologies involved are:

涉及的技术有:

  • Angular for the general front-end application
  • SockJS for creating websocket communication
  • Stomp over webosocket for receiving messages from a message broker
  • Springboot Websockets
  • Stomp Message Broker (the java related framework)
  • 一般前端应用的Angular
  • 用于创建 websocket 通信的 SockJS
  • 踩过 webosocket 以从消息代理接收消息
  • Springboot Websockets
  • Stomp Message Broker(java相关框架)

What I want to achieve on the front end is:

我想在前端实现的是:

  1. Create a websocket connection when the view is loaded
  2. Create s stomp provider using that websocket
  3. Have my client subscribe to it
  4. Catch server pushed messages and update the angular view
  1. 加载视图时创建 websocket 连接
  2. 使用该 websocket 创建 stomp provider
  3. 让我的客户订阅它
  4. 捕获服务器推送消息并更新角度视图

As far as the server side code:

至于服务器端代码:

  1. Configure the websocket stuff and manage the connection
  2. Have the server push messages every X amount of time (through an executor or @Scheduled?).
  1. 配置 websocket 的东西并管理连接
  2. 让服务器每 X 时间推送一次消息(通过执行程序或@Scheduled?)。

I think I have achieved everything so far except the last part of the server side code. The example I was following uses the websocket in full duplex mode and when a client sends something then the server immediately responds to the message queue and all subscribed clients update. But what I want is for the server itself to send something over StompWITHOUT waiting for the client to make any requests.

我想到目前为止,除了服务器端代码的最后一部分之外,我已经实现了一切。我下面的示例在全双工模式下使用 websocket,当客户端发送某些内容时,服务器会立即响应消息队列并更新所有订阅的客户端。但我想要的是服务器本身在Stomp不等待客户端发出任何请求的情况下发送一些内容。

At first I created a spring @Controllerand added a method to it with @SendTo("/my/subscribed/path")annotation. However I have no idea how to trigger it. Also I tried adding @Scheduledbut this annotation works only on methods with voidreturn type (and I'm returning a NewsMessage object).

一开始我创建了一个弹簧@Controller并添加了一个带有@SendTo("/my/subscribed/path")注释的方法。但是我不知道如何触发它。我也尝试添加,@Scheduled但此注释仅适用于具有void返回类型的方法(并且我返回的是 NewsMessage 对象)。

Essentially what I need is to have the client initialize a websocket connection, and after have the server start pushing messages through it at a set interval (or whenever an event is triggered it doesn't matter for now). Also, every new client should listen to the same message queue and receive the same messages.

本质上,我需要的是让客户端初始化一个 websocket 连接,然后让服务器以设定的时间间隔开始通过它推送消息(或者每当触发事件时,现在都无关紧要)。此外,每个新客户端都应该侦听相同的消息队列并接收相同的消息。

采纳答案by RMachnik

First of all you need tho have your websocketenabled in spring, before make sure that you have according dependencies in your pom.xml

首先,您需要websocket在 spring 中启用您的功能,然后再确保您的应用程序中具有相应的依赖项pom.xml

For instance most important one:

例如最重要的一个:

         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

Then you need to have your configuration in place. I suggest you to start with simple broker.

然后你需要有你的配置。我建议你从简单的经纪人开始。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/portfolio").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.setApplicationDestinationPrefixes("/app");
        config.enableSimpleBroker("/topic", "/queue");
    }

}

Then your controller should look like this. When your AngularJsapp will open connection on '/portfolio' and send subscription to this channel /topic/greeetingyou will receive this in controller and respond to all subscribed users.

那么你的控制器应该是这样的。当您的AngularJs应用程序将在“/portfolio”上打开连接并向此频道发送订阅时,/topic/greeeting您将在控制器中收到此信息并响应所有订阅用户。

@Controller
public class GreetingController {

    @MessageMapping("/greeting")
    public String handle(String greeting) {
        return "[" + getTimestamp() + ": " + greeting;
    }
}

Regarding your scheduler question, you need to enable it via configuration:

关于您的调度程序问题,您需要通过配置启用它:

@Configuration
@EnableScheduling
public class SchedulerConfig{}

And then schedule it:

然后安排它:

@Component
public class ScheduledUpdatesOnTopic{

    @Autowired
    private SimpMessagingTemplate template;
    @Autowired
    private final MessagesSupplier messagesSupplier;

    @Scheduled(fixedDelay=300)
    public void publishUpdates(){
        template.convertAndSend("/topic/greetings", messagesSupplier.get());
    }
}

Hope this somehow clarified concept and steps needs to be taken to make things working for you.

希望这个以某种方式澄清的概念和需要采取的步骤使事情对你有用。

//Note: Made changes @Scheduler to @Scheduled

//注意:将@Scheduler 更改为@Scheduled

回答by Artem Bilan

First of all you can't send (push) messages to clients without their subscriptions.

首先,您不能在没有订阅的情况下向客户端发送(推送)消息。

Secondly to send messages to all subscribers you should take a look to the topicabstraction side.

其次,要向所有订阅者发送消息,您应该查看topic抽象方面。

That is a fundamentals of STOMP.

这是 STOMP 的基础。

I think you are fine with @Scheduled, but you just need to inject SimpMessagingTemplateto send messages to the STOMP broker for pushing afterwards.

我认为您可以使用@Scheduled,但您只需要注入SimpMessagingTemplate即可将消息发送到 STOMP 代理以进行推送。

Also see Spring WebSockets XML configuration not providing brokerMessagingTemplate

另请参阅不提供 brokerMessagingTemplate 的 Spring WebSockets XML 配置