java - Spring Boot WebSocketStompClient 未收到消息
问题描述
目前,我可以看到在测试用例中我能够成功连接并向 WS 服务器/端点发送消息。但是,我没有收到任何消息。测试用例中的completeableFuture
对象等待消息 10 秒然后超时。我也尝试调试源代码,其中我可以session
看到destination
正确subscribers
加载
我的 WebSocket 配置:
@EnableWebSocketMessageBroker
class WebSocketConfig : WebSocketMessageBrokerConfigurer {
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS()
}
override fun configureMessageBroker(registry: MessageBrokerRegistry) {
registry.enableSimpleBroker( "/topic/")
registry.setApplicationDestinationPrefixes("/api/")
//registry.setUserDestinationPrefix("/user")
}
控制器:
class ChatController(private val chatService: ChatService) {
@MessageMapping("/user/chat/{channelId}")
@SendTo("/topic/chat/{channelId}")
fun chatMessage(@DestinationVariable("channelId") channelId: UUID, chatMessageDTO: ChatMessageDTO): ChatNotification {
return chatService.submitMessage(chatMessageDTO, channelId)
}
服务:
fun establishChatSession(chatChannelDTO: ChatChannelDTO): ChatChannelDTO {
if (chatChannelDTO.userOne == chatChannelDTO.userTwo) {
throw InvalidInputDataException("")
}
val optionalChatChannel = getExistingChannel(chatChannelDTO)
return if (optionalChatChannel.isPresent) {
ChatChannelDTO.fromChatChannel(optionalChatChannel.get())
} else {
newChatSession(chatChannelDTO)
}
}
测试 :
class ChatControllerIT(@Autowired private val chatService: ChatService, @Autowired private val simpleMessagingTemplate: SimpMessagingTemplate) {
@Value("\${local.server.port}")
var port = 0;
var completableFuture: CompletableFuture<ChatNotification> = CompletableFuture()
lateinit var webSocketStompClient: WebSocketStompClient
@BeforeEach
fun setup() {
this.webSocketStompClient = WebSocketStompClient(SockJsClient(listOf(WebSocketTransport(StandardWebSocketClient()))))
webSocketStompClient.messageConverter = MappingJackson2MessageConverter()
}
@Test
fun verifyGreetingIsReceived() {
val channel = chatService.establishChatSession(ChatChannelDTO(userOne = UUID.randomUUID(), userTwo = UUID.randomUUID()))
val stompSession = webSocketStompClient.connect("ws://localhost:$port/ws", object : StompSessionHandlerAdapter() {}).get(10, TimeUnit.SECONDS)
println("subscribing to:::::::::: /topic/chat/${channel.channelId}")
val message = ChatMessageDTO(message = "Hello", senderId = channel.userOne, senderName = "Pranav", recipientName = "Monika", recipientId = channel.userTwo)
stompSession.send("/api/user/chat/${channel.channelId}", message)
stompSession.subscribe("/topic/chat/${channel.channelId}", object: StompFrameHandler{
override fun getPayloadType(headers: StompHeaders): Type {
return ChatNotification::class.java
}
override fun handleFrame(headers: StompHeaders, @Nullable payload: Any?) {
completableFuture.complete(payload as ChatNotification)
}
})
val response = completableFuture.get(10, TimeUnit.SECONDS)
println(response)
}
}
关于这里出了什么问题的任何想法?
解决方案
这段代码对我来说是正确的。我创建了示例项目并且它有效。您确定 local.server.port 具有正确的值。试试这个测试课。如果它不起作用,请直接与我联系,我将向您发送示例项目
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ChatControllerIT(@Autowired private val chatService: ChatService) {
@LocalServerPort
var port = 0
var completableFuture: CompletableFuture<ChatNotification> = CompletableFuture()
lateinit var webSocketStompClient: WebSocketStompClient
@BeforeEach
fun setup() {
this.webSocketStompClient = WebSocketStompClient(SockJsClient(listOf(WebSocketTransport(StandardWebSocketClient()))))
webSocketStompClient.messageConverter = MappingJackson2MessageConverter()
}
@Test
fun verifyGreetingIsReceived() {
val channel = chatService.establishChatSession(ChatChannelDTO(userOne = UUID.randomUUID(), userTwo = UUID.randomUUID()))
val stompSession = webSocketStompClient.connect("ws://localhost:$port/ws", object : StompSessionHandlerAdapter() {}).get(10, TimeUnit.SECONDS)
println("subscribing to:::::::::: /topic/chat/${channel.channelId}")
val message = ChatMessageDTO(message = "Hello", senderId = channel.userOne, senderName = "Pranav", recipientName = "Monika", recipientId = channel.userTwo)
stompSession.send("/api/user/chat/${channel.channelId}", message)
stompSession.subscribe("/topic/chat/${channel.channelId}", object: StompFrameHandler {
override fun getPayloadType(headers: StompHeaders): Type {
return ChatNotification::class.java
}
override fun handleFrame(headers: StompHeaders, @Nullable payload: Any?) {
completableFuture.complete(payload as ChatNotification)
}
})
val response = completableFuture.get(10, TimeUnit.SECONDS)
println(response)
}
}
推荐阅读
- ruby-on-rails - 我正在编写 Micheal Hartls Rail Tutorial 这本书我使用了相同的代码但得到了不同的结果
- ruby-on-rails - 如何在日志记录中过滤部分路径(不是参数)?
- flutter - 如何在 Flutter Web 中的 Row 中调整 IconButton 的大小?图标大小呈现在行视图之外
- laravel - 未找到 Laravel 5.8 类“Doctrine\DBAL\Driver\PDOMySql\Driver”
- python - 我需要我的代码只接受浮点值
- mysql - 连接到同一 DBMS 上的“外部”数据库
- java - 使用 Spring Boot 解析未转义的 Json
- javascript - 使用基本身份验证获取对 localhost 的请求
- time - 简单的任务:我希望在单击“尝试”后发生的事情发生,而实际上不需要单击按钮
- pine-script - PineScript 如何解析“如果 series1 > series2”?