Spring Websocket+SockJS+STOMP 实现即时通信(四)—— MessageHandler


MessageHandler的作用

上一节中我们提到过,ExecutorSubscribableChannel类持有一个实例handlers —— MessageHandler集合,是MessageChannel的订阅者,用来作为处理Messages的约定。

MessageHandler是一个接口,它的实现类都必须实现方法 —— handleMessage(Message<?> message)用来处理消息Message —— 从外部接收的从应用程序内部传递的

/**
 * Contract for handling a {@link Message}.
 *
 * @author Mark Fisher
 * @author Iwein Fuld
 * @since 4.0
 */
public interface MessageHandler {
	/**
	 * Handle the given message.
	 * @param message the message to be handled
	 */
	void handleMessage(Message<?> message) throws MessagingException;
}

MessageHandler实现类

MessageHandler 的具体实现类共有 两类九种,分别用来处理不同类型的Message

  • 未实现org.springframework.context.SmartLifecycle接口
    • UserRegistryMessageHandler
    • NoOpMessageHandler
  • 实现org.springframework.context.SmartLifecycle接口
    • SubProtocolWebSocketHandler
    • SimpAnnotationMethodMessageHandler
    • WebSocketAnnotationMethodMessageHandler
    • NoOpBrokerMessageHandler
    • SimpleBrokerMessageHandler
    • StompBrokerRelayMessageHandler
    • UserDestinationMessageHandler

两类MessageHandler有什么区别?

  • 先来看下org.springframework.context.SmartLifecycle接口 —— 智能生命周期,是org.springframework.context.Lifecycleorg.springframework.context.Phased的扩展。说白了:只要你实现了SmartLifeCycle接口,你便可以在任何时候判断Bean所处的生命周期,并可以通过实现指定方法在指定的生命周期去搞事情
SmartLifecycle :
 public interface SmartLifecycle extends Lifecycle, Phased {
   boolean isAutoStartup();
   void stop(Runnable callback);
}
  • 就拿AbstractBrokerMessageHandler来说,它是NoOpBrokerMessageHandler、SimpleBrokerMessageHandler和StompBrokerRelayMessageHandler的父类接口,实现了SmartLifecycle ,在start()stop()方法中分别实现了对相关MessageChannel订阅取消订阅
  • 到这里我们可以明白,不实现SmartLifecycle接口的那类MessageHandler就是不需要绑定MessageChannel,相反另一类则是用来在指定生命周期订阅或解订阅MessageChannel。
AbstractBrokerMessageHandler:
public abstract class AbstractBrokerMessageHandler
   	implements MessageHandler, ApplicationEventPublisherAware, SmartLifecycle {
   @Override
   public boolean isAutoStartup() {
   	return this.autoStartup;
   }
   @Override
   public int getPhase() {
   	return Integer.MAX_VALUE;
   }
   @Override
   public void start() {
   	synchronized (this.lifecycleMonitor) {
   		logger.info("Starting...");
   		this.clientInboundChannel.subscribe(this);
   		this.brokerChannel.subscribe(this);
   		if (this.clientInboundChannel instanceof InterceptableChannel) {
   			((InterceptableChannel) this.clientInboundChannel).addInterceptor(0, this.unsentDisconnectInterceptor);
   		}
   		startInternal();
   		this.running = true;
   		logger.info("Started.");
   	}
   }
   @Override
   public void stop() {
   	synchronized (this.lifecycleMonitor) {
   		logger.info("Stopping...");
   		stopInternal();
   		this.clientInboundChannel.unsubscribe(this);
   		this.brokerChannel.unsubscribe(this);
   		if (this.clientInboundChannel instanceof InterceptableChannel) {
   			((InterceptableChannel) this.clientInboundChannel).removeInterceptor(this.unsentDisconnectInterceptor);
   		}
   		this.running = false;
   		logger.info("Stopped.");
   	}
   }
   @Override
   public final void stop(Runnable callback) {
   	synchronized (this.lifecycleMonitor) {
   		stop();
   		callback.run();
   	}
   }
   @Override
   public final boolean isRunning() {
   	return this.running;
   }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Spring Boot和WebSocket的完整配置步骤: 1. 创建一个Spring Boot项目并添加相关依赖: 在`pom.xml`文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 创建WebSocket处理器: ```java import org.springframework.stereotype.Component; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketSession; @Component public class MyWebSocketHandler implements WebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 当WebSocket连接建立时执行的逻辑 } @Override public void handleMessage(WebSocketSession session, TextMessage message) throws Exception { // 处理接收到的WebSocket消息 } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { // 当WebSocket连接关闭时执行的逻辑 } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { // 处理传输错误的逻辑 } } ``` 3. 配置WebSocket: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { private final MyWebSocketHandler webSocketHandler; @Autowired public WebSocketConfig(MyWebSocketHandler webSocketHandler) { this.webSocketHandler = webSocketHandler; } @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(webSocketHandler, "/websocket") .setAllowedOrigins("*"); } } ``` 4. 在应用程序的入口类上添加`@EnableWebSocket`注解: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication @EnableAsync public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 5. 创建控制器: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Controller; @Controller public class WebSocketController { @MessageMapping("/hello") @SendTo("/topic/greetings") public String greeting(String message) { return "Hello, " + message + "!"; } } ``` 在上述代码中,`@MessageMapping`注解用于指定接收WebSocket消息的目标地址,`@SendTo`注解用于指定发送消息的目标地址。 6. 创建前端页面: 在你的前端页面中,使用JavaScript连接到WebSocket服务器并发送消息,可以使用`Stomp.js`和`SockJS`库来简化操作。例如: ```javascript var stompClient = null; function connect() { var socket = new SockJS('/websocket'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { stompClient.subscribe('/topic/greetings', function(response) { var message = JSON.parse(response.body); showMessage(message); }); }); } function showMessage(message) { // 处理接收到的消息 } function sendMessage(message) { stompClient.send("/hello", {}, message); } ``` 在上述代码中,`connect()`函数用于建立WebSocket连接,`showMessage()`函数用于处理接收到的消息,`sendMessage()`函数用于发送消息。 7. 运行应用程序: 运行Spring Boot应用程序,访问前端页面,即可进行WebSocket通信。 以上是使用Spring Boot和WebSocket的完整配置步骤。你可以根据自己的需求进行调整和扩展。希望对你有所帮助!如有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值