我的要求是,一旦后端发生一些变化,就通过网络套接字发送(广播)消息。
我跟着this tutorial并利用this question中的答案提出了一个解决方案,通过定期调用方法来发送消息。
我的Web套接字控制器类 - GreetingController类是这样的,
@Controller
public class GreetingController {
@Autowired
private SimpMessagingTemplate template;
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
FireGreeting r = new FireGreeting( this );
new Thread(r).start();
return new Greeting("Hello world !");
}
public void fireGreeting() {
System.out.println("Fire");
this.template.convertAndSend("/topic/greetings", new Greeting("Fire"));
}
}
在线程类中调用fireGreeting方法 - FireGreeting
public class FireGreeting implements Runnable {
private GreetingController listener;
public FireGreeting( GreetingController listener) {
this.listener = listener;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep( 2000 );
listener.fireGreeting();
} catch ( InterruptedException e ) {
e.printStackTrace();
}
}
}
}
当我运行这个项目时,我可以最初发送一条消息然后线程开始定期调用fireGreeting()方法。
如果不调用问候语(HelloMessage消息)方法,我不会这样做, 每当我的后端操作运行时调用fireGreeting()方法。
我尝试单独调用该方法但它提供了一个空指针异常,因为此时SimpMessagingTemplate template;
未初始化。
我的问题如下, 1.什么时候模板对象被初始化? (所以我可以做同样的事情并用它来调用convertAndSend()方法)
是否无法按照我尝试的方式调用convertAndSend方法?
我有没有其他方法可以在春天和websocket中达到这个要求?
我也试过了this code in the documentation,但我对它的运作方式并不清楚。 看起来,我可以发送一个POST调用并调用greet()方法,以便它向服务器发送一条消息。 但我想要的是仅从服务器端调用该方法。
任何关于此的建议都会有很大的帮助。 :)
答案 0 :(得分:1)
有点晚了,但是我有个问题。 在How to send message to client through websocket using Spring
上找到了答案我可以举另一个代码示例:
package xxx.web.websocket;
import xxx.web.websocket.dto.GameEventDTO;
import java.security.Principal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.messaging.handler.annotation.*;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
@Controller
public class GameEventService implements ApplicationListener<SessionDisconnectEvent> {
private static final Logger log = LoggerFactory.getLogger(GameEventService.class);
public GameEventService() {
}
// this method is in all examples : receive from a client, send to all
@MessageMapping("/topic/eventToServer")
@SendTo("/topic/eventToClient")
public GameEventDTO sendGameEvent(@Payload GameEventDTO dto, StompHeaderAccessor stompHeaderAccessor,
Principal principal) {
log.debug("Sending game event {}", dto);
return dto;
}
@Override
public void onApplicationEvent(SessionDisconnectEvent event) {
log.debug("game event SessionDisconnectEvent");
}
@Autowired
private SimpMessagingTemplate template;
// the business logic can call this to update all connected clients
public void sendGameEventFromJava(GameEventDTO dto) {
log.debug("Sending game event from java {}", dto);
this.template.convertAndSend("/topic/eventToClient", dto);
}
}
我的业务逻辑称之为:
@Service
@Transactional
public class GameService {
private final Logger log = LoggerFactory.getLogger(GameService.class);
private final GameRepository gameRepository;
private final GameEventService gameEventService;
public GameService(GameRepository gameRepository, GameEventService gameEventService) {
this.gameRepository = gameRepository;
this.gameEventService = gameEventService;
}
/**
* Save a game.
*
* @param game the entity to save
* @return the persisted entity
*/
public Game save(Game game) {
log.debug("Request to save Game : {}", game);
Game result = gameRepository.save(game);
GameEventDTO dto = new GameEventDTO();
dto.setGameId(result.getId());
this.gameEventService.sendGameEventFromJava(dto);
return result;
}
...
对于您而言,SimpMessagingTemplate模板应为init。 这是一些项目配置问题。 例如,确保您拥有所有的Maven / Gradle组件。 我将其添加到我的pom.xml中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId>
</dependency>
通过websocket祝大家好运。