简体   繁体   English

WebSocket STOMP 已经覆盖 class 主要方法 getname() convertAndSendToUser 不起作用

[英]WebSocket STOMP already override class principal method getname() convertAndSendToUser doesn't work

I just want to test if convertAndSendToUser is working or not.我只想测试convertAndSendToUser是否正常工作。 If you have the same problem or experience please help me to fix it.如果您有同样的问题或经历,请帮助我解决它。

You can see the method when I use the code upder it it same to ok( convertAndSend ).当我使用代码更新时,您可以看到方法,它与 ok( convertAndSend )相同。 When I use convertAndSendToUser my html can not get the STOMP message.当我使用convertAndSendToUser时,我的 html 无法获得 STOMP 消息。 So I guess destination is right,but something wrong I can't found;所以我猜目的地是对的,但我找不到错的地方;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Resource
    private WebSocketHandshakeInterceptor webSocketHandshakeInterceptor;

    @Autowired
    private WebSocketService webSocketService;

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint(PathConstant.STOMP_CHAT_CHANNEL).addInterceptors(webSocketHandshakeInterceptor).setAllowedOrigins("*").withSockJS();        registry.addEndpoint(PathConstant.STOMP_CLASS_COMMEND).setAllowedOrigins("*").withSockJS().setInterceptors(webSocketHandshakeInterceptor);

        // test
        registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS().setInterceptors(webSocketHandshakeInterceptor);
    }


    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker(PathConstant.TOPIC, PathConstant.USER);
        registry.setApplicationDestinationPrefixes(PathConstant.APP);
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {

        registration.interceptors(new ChannelInterceptor() {
            @Override
            public Message<?> preSend(Message<?> message, MessageChannel channel) {
                StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
                if (StompCommand.CONNECT.equals(accessor.getCommand())) {

                    String token = accessor.getFirstNativeHeader("Auth_token");

                    String username = webSocketService.checkToken(token).getUser_name();
                    String uid = UUID.randomUUID().toString().replace("-", "");

                    SocketUser user = new SocketUser(uid,username);

                    accessor.setUser(user);

                    webSocketService.addSocketCache(uid, user);
                }
                return message;
            }
        });
    }
}
public class SocketUser implements Principal, Serializable {

    private static final long serialVersionUID = -2882674220040446492L;

    private final String username;

    private final String userId;

    public SocketUser(String userId,String username) {
        this.userId = userId;
        this.username = username;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public String getUsername() {
        return username;
    }


    public String getUserId() {
        return userId;
    }



    @Override
    public String getName() {
        return userId;
    }

}

@RestController
public class ChatroomController {

private final Logger logger = LoggerFactory.getLogger(ChatroomController.class);

@Autowired
private MessageService messageService;

@Autowired
private Gson gson;

@Autowired
ChatroomMessageRepository chatroomMessageRepository;

@Autowired
ChatroomUserRepository chatroomUserRepository;

@Autowired
private SimpMessageSendingOperations messagingTemplate;

//    @Autowired
//    private SimpMessagingTemplate messagingTemplate;

@Autowired
private SimpUserRegistry userRegistry;

@Autowired
WebSocketService webSocketService;

@MessageMapping(PathConstant.STOMP_CHAT_ADD_USER)
@SendTo(PathConstant.TOPIC_PUBLIC)
public ChatMessage addUser(@Payload ChatMessage chatMessage, StompHeaderAccessor accessor) {
    userRegistry.getUsers().stream().forEach(System.out::println);
    accessor.getSessionAttributes().put("username", chatMessage.getSender());
    chatMessage.setUid(accessor.getUser().getName());
    return chatMessage;
}

@MessageMapping(PathConstant.STOMP_CHAT_ADD_MESSAGE)
@SendTo(PathConstant.TOPIC_PUBLIC)
public ChatMessage addMessage(@Payload ChatMessage chatMessage, StompHeaderAccessor accessor) {
    return chatMessage;
}

@MessageMapping(PathConstant.USER_CHAT)
public void sendToUser(@Payload ChatMessage chatMessage, StompHeaderAccessor accessor) {
    String uid = accessor.getUser().getName();
    chatMessage.setType(ChatMessage.MessageType.CHAT);
    System.out.println("/user/" + uid + "/chat");
    messagingTemplate.convertAndSendToUser(uid, "/user/" + uid + "/chat", chatMessage);
//        messagingTemplate.convertAndSend("/user/" + uid + "/chat" , chatMessage);
}
}

I'm having trouble following your post but the way I do it in my rest controllers is like so:我在关注您的帖子时遇到了麻烦,但我在 rest 控制器中的操作方式是这样的:

   @ApiOperation(
        value = "Returns the current SDDF Host/Port the bridge is connected to",
        produces = "application/json",
        notes =
        """
# STOMP Enabled
To access this endpoint via a **STOMP** websocket
* Send a message to: `/app/rest/sddf_info`
* Subscribe to: `/user/queue/rest/sddf_info`
    """
    )
    @GetMapping("/sddf_info")
    @MessageMapping("/rest/sddf_info")
    @SendToUser
    fun getSDDFInfo(): SDDFInfo {
        return SDDFInfo(
            sddfConfigProperties.hostName,
            sddfConfigProperties.hostPort
        )
    }

You can hit this controller 2 ways:您可以通过 2 种方式点击此 controller:

  • http get to /sddf_info http 到达/sddf_info
  • Sending a STOMP message to /app/rest/sddf_info/app/rest/sddf_info发送 STOMP 消息

If you subscribe to /user/queue/rest/sddf_info the @SendToUser will deliver the response from the stomp incoming message to /app/rest/sddf_info to that topic如果您订阅/user/queue/rest/sddf_info@SendToUser会将来自 stomp 传入消息的响应传递到/app/rest/sddf_info到该主题

I have a configuration:我有一个配置:

@Configuration
@EnableWebSocketMessageBroker
class STOMPWebSocketConfig : WebSocketMessageBrokerConfigurer {

....

   override fun configureMessageBroker(config: MessageBrokerRegistry) {
        config.enableSimpleBroker("/topic", "/queue")
        config.setApplicationDestinationPrefixes("/app")
        config.setUserDestinationPrefix("/user")
    }

That configures some of these endpoints locations..这配置了其中一些端点位置..

(also this code is Kotlin not Java - but Kotlin is 100% java compatible... so if you are writing java you should be able to figure it out from here) (also this code is Kotlin not Java - but Kotlin is 100% java compatible... so if you are writing java you should be able to figure it out from here)

Is this what your are asking... how to use the user queue ( @SendToUser ) correctly?这是您要问的……如何正确使用用户队列( @SendToUser )?

super.convertAndSend(this.destinationPrefix + user + destination, payload, headers, postProcessor); super.convertAndSend(this.destinationPrefix + user + destination, payload, headers, postProcessor); private String destinationPrefix = "/user/";私有字符串destinationPrefix = "/user/"; spring-message already put your uid and "user" in your destination, so you can use like this " messagingTemplate.convertAndSendToUser(uid, "/chat", chatMessage)" spring-message 已经将您的 uid 和“用户”放在您的目的地,因此您可以像这样使用“messagingTemplate.convertAndSendToUser(uid, "/chat", chatMessage)"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM