当他连接到 spring websocket 时如何向用户发送消息

How to send message to user when he connects to spring websocket

我想在用户连接到 spring websocket 时向他发送消息,我已经

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Autowired
    private GenervicSerice<User> userService;
    @Autowired 
    private SimpMessagingTemplate template; 
    private CurrentUser currnetUser;
    @Override
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        // TODO Auto-generated method stub
        stompEndpointRegistry.addEndpoint("/ws").withSockJS();
    }

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

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {

        registration.setInterceptors(myChannelInterception());
        try {
            updateNotificationAndBroadcast();

        } catch (Exception e) {
            return;
        }
    }

    @Bean
    public MyChannelInterception myChannelInterception() {
        return new MyChannelInterception();
    }


    private void updateNotificationAndBroadcast() {    
        try {               
            template.convertAndSend("/queue/notify", "Greetings");
        } catch (Exception e) {
            System.out.println("Error message is " + e.getMessage() + "\n\n\n" + "Caused by " + e.getCause()
                    );
        }

    }

}

MyChannelInterception class 是

public class ImtehanChannelInterception extends ChannelInterceptorAdapter {     

    private CurrentUser currnetUser;

    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {

        MessageHeaders headers = message.getHeaders();
        SimpMessageType type = (SimpMessageType) headers.get("simpMessageType");
        String simpSessionId = (String) headers.get("simpSessionId");
        currnetUser = new CurrentUser();
        if (type == SimpMessageType.CONNECT) {
            Principal principal = (Principal) headers.get("simpUser");
            currnetUser.setCurrentUserEmail(principal.getName());
            System.out.println("WsSession " + simpSessionId
                    + " is connected for user " + principal.getName());
        } else if (type == SimpMessageType.DISCONNECT) {
            System.out.println("WsSession " + simpSessionId
                    + " is disconnected");
        }

        return message;
    }

}

通过这个我获得了有关新连接用户的信息,但是 WebSocketConfig 中的方法 updateNotificationAndBroadcast() 没有向新登录用户发送消息。

我会创建 SessionSubscribeEvent 侦听器并在其中使用 SimpMessagingTemplate

顺便说一句,configureClientInboundChannel 只被调用一次(不是针对每个连接的用户)。所以你必须在拦截器中处理发送消息。

尝试这样的事情:

@Service
public class SomeSubscribeListener {

    private SimpMessagingTemplate template;

    @Autowired
    public SomeSubscribeListener(SimpMessagingTemplate template) {
        this.template = template;
    }

    @EventListener
    public void handleSubscribeEvent(SessionSubscribeEvent event) {
        template.convertAndSendToUser(event.getUser().getName(), "/queue/notify", "GREETINGS");
    }
}

希望对您有所帮助

您需要一个 Websocketconfig 文件:

package mx.config.ws;
@EnableScheduling
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
   @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
       registry.addEndpoint("/chat").withSockJS()
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
    ...
    }
}

并声明另一个@Configuration 文件:

package mx.config.ws;
@Configuration
public class WebSocketHandlersConfig {

    @Bean
    public StompConnectEvent webSocketConnectHandler() {
        return new StompConnectEvent();
    }

    @Bean
    public StompDisconnectEvent webSocketDisconnectHandler() {
        return new StompDisconnectEvent();
    }
}

接下来创建 ApplicationListener 接口的实现。您将自动拦截 STOMP 连接

package mx.config.ws;
public class StompConnectEvent implements ApplicationListener<SessionConnectEvent> {

    @Override
    public void onApplicationEvent(SessionConnectEvent event) {

         StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());

         System.out.println("StompConnectEvent::onApplicationEvent()    sha.getSessionId(): "+sha.getSessionId()+" sha.toNativeHeaderMap():"+sha.toNativeHeaderMap());


         //String  company = sha.getNativeHeader("company").get(0);
         //logger.debug("Connect event [sessionId: " + sha.getSessionId() +"; company: "+ company + " ]");



         // HERE YOU CAN MAYBE SEND A MESSAGE

    }

}

查看此 link 以获取相关信息:
http://www.sergialmar.com/2014/03/detect-websocket-connects-and-disconnects-in-spring-4/

Spring 文档表明您需要实现 Spring 的应用程序侦听器接口。

26. WebSocket Support -> 26.4.14 Events and Interception

以下代码是会话订阅事件的示例。您可以在提供的 link 中找到所有可能的事件,包括连接事件。

@Component
public class VSignNewSubscriptionsListener implements ApplicationListener<SessionSubscribeEvent> {
@Override
  public void onApplicationEvent(SessionSubscribeEvent event) {
  }
}