0

I have such problem. When i try to send message from client side to server, it doesn't match with my @MessageMapping methods. I don't know how to intercept messages on controller layer.

Client side sends message (it's react-stomp that uses sockjs):

move = (move) => {
    this.clientRef.sendMessage("/user/${this.state.opponentId}/queue/move", JSON.stringify(move))
};

Server side. WebSocketConfig:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/handler")
                .setHandshakeHandler(new CustomHandshakeHandler())
                .setAllowedOrigins("http://localhost:3000")
                .withSockJS();
    }

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

    @EventListener
    void handleSessionConnectedEvent(SessionConnectedEvent event) {
        StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(new MyChannelInterceptor());
    }

}

I also added interceptor class to check path of incomming message:

public class MyChannelInterceptor implements ChannelInterceptor {

    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
        return message;
    }
}

On debugging of MyChannelInterceptor i see message with payload and headers. There is simpDestination header with such value:

/user/baedde36-0f9e-4fa5-b8d7-687db1dbcd67/queue/move

What @MessageMapping value should i write to handle messages from specified users? This message succesfully gets to frontside by subscription on this topic but doesn't stay on any controller:

`/user/${message}/queue/move`

I just want to handle messages on server side but i can't catch it there.

1 Answers1

0

Okay. As i understood there is 3 ways to handle websocket messages:

/app - handles with controller
/user - handles with broker, sends messages to specific users
/topic - broadcast to topic for all subscribers

In my situation i just need to create json object with userId, receiverId and message. On server side add DTO class and get it as attribute in my controller method.

Solution:

move = (move) => {
    let moveDto = {move: move, userId: this.state.userId, opponentId: this.state.opponentId}
    this.clientRef.sendMessage(`/app/move`, JSON.stringify(moveDto))
};

Server side:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class MoveDto {
    private String userId;
    private String opponentId;
    private int move;
}

Controller class:

@RestController
public class GameController {

@Autowired
private SimpMessagingTemplate simpMessagingTemplate;

...//some code here

@MessageMapping("/move")
public void message(MoveDto moveDto) {
String userMessage= "foo";
String opponentMessage = "bar";

 simpMessagingTemplate.convertAndSendToUser(
            moveDto.getUserId(), "/queue/message", userMessage);

 simpMessagingTemplate.convertAndSendToUser(
            moveDto.getOpponentId(), "/queue/message", opponentMessage );
}