如何使用Spring 4在我的WebSocket服务器中捕获订阅事件

14

我使用Spring 4、STOMP和sock.js进行了简单的WebSocket通信,参考了这个文档:https://spring.io/guides/gs/messaging-stomp-websocket/

现在我想将它升级为简单的聊天应用。我的问题是,当用户订阅新的聊天室时,他应该能够获取历史消息。我不知道如何在他订阅后立即捕获这一时刻并向他发送消息列表。

我尝试使用@MessageMapping注释,但没有成功:

@Controller
public class WebSocketController {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;


    @MessageMapping("/chat/{chatId}")
    public void chat(ChatMessage message, @DestinationVariable String chatId) {
        messagingTemplate.convertAndSend("/chat/" + chatId, new ChatMessage("message: " + message.getText()));
    }

    @SubscribeMapping("/chat")
    public void chatInit() {
        System.out.println("worked");
        int chatId = 1; //for example
        messagingTemplate.convertAndSend("/chat/" + chatId, new ChatMessage("connected"));
    }

}

然后我创造了那个:

@Controller
public class ApplicationEventObserverController implements ApplicationListener<ApplicationEvent> {
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        System.out.println(applicationEvent);
    }
}

它能够工作,但捕获了所有可能的事件,我认为这不是一个好的实践方法。

所以,我的问题可以重新表述为:如何在用户订阅某些内容时发送初始数据?


我在这里找到了类似的问题:https://dev59.com/l2Af5IYBdhLWcg3wUBNc - sinedsem
看起来和这个问题很相似。请查看我在那里的回答,看看是否对您有用。 - croc
1个回答

13

当客户端使用@SubscribeMapping处理程序方法订阅目标时,您可以直接向客户端返回任何东西。返回的对象不会发送到代理,而是将直接发送到客户端:

@SubscribeMapping("/chat")
public Collection<ChatMessage> chatInit() {
    ...
    return messages;
}

在客户端:

socket.subscribe("/app/chat", function(message) {
    ...
});

请查看GitHub上的聊天示例,该示例展示了此确切情况。


2
仍然无法得到我想要的东西。@Sergi Almar,我能订阅一次并使用此订阅获取初始消息和将来的消息吗? - sinedsem
@SubscribeMapping 只有在我写 stompClient.subscribe("/app/chat/") 时才能工作,但在这种情况下,我无法接收新消息。 - sinedsem
@SubscribeMapping 旨在用于请求-应答场景,因此无法捕获主题订阅事件。 - hello.wjx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接