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
Scheduled websocket push with Springboot
提问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:
我想在前端实现的是:
- Create a websocket connection when the view is loaded
- Create s stomp provider using that websocket
- Have my client subscribe to it
- Catch server pushed messages and update the angular view
- 加载视图时创建 websocket 连接
- 使用该 websocket 创建 stomp provider
- 让我的客户订阅它
- 捕获服务器推送消息并更新角度视图
As far as the server side code:
至于服务器端代码:
- Configure the websocket stuff and manage the connection
- Have the server push messages every X amount of time (through an executor or
@Scheduled
?).
- 配置 websocket 的东西并管理连接
- 让服务器每 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 Stomp
WITHOUT waiting for the client to make any requests.
我想到目前为止,除了服务器端代码的最后一部分之外,我已经实现了一切。我下面的示例在全双工模式下使用 websocket,当客户端发送某些内容时,服务器会立即响应消息队列并更新所有订阅的客户端。但我想要的是服务器本身在Stomp
不等待客户端发出任何请求的情况下发送一些内容。
At first I created a spring @Controller
and added a method to it with @SendTo("/my/subscribed/path")
annotation. However I have no idea how to trigger it. Also I tried adding @Scheduled
but this annotation works only on methods with void
return 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 websocket
enabled 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 AngularJs
app will open connection on '/portfolio' and send subscription to this channel /topic/greeeting
you 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 topic
abstraction side.
其次,要向所有订阅者发送消息,您应该查看topic
抽象方面。
That is a fundamentals of STOMP.
这是 STOMP 的基础。
I think you are fine with @Scheduled
, but you just need to inject SimpMessagingTemplate
to send messages to the STOMP broker for pushing afterwards.
我认为您可以使用@Scheduled
,但您只需要注入SimpMessagingTemplate
即可将消息发送到 STOMP 代理以进行推送。
Also see Spring WebSockets XML configuration not providing brokerMessagingTemplate