SpringBoot集成WebSocket--------Spring方式集成(一)

一、引入依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
   <version>2.7.0</version>
</dependency>

二、配置

1、WebSocketConfigurer配置器

/**
 *  实现回调方法registerWebSocketHandlers(会被@EnableWebSocket注解获取并回调)配置WebSocket的请求处理逻辑
 */
public interface WebSocketConfigurer {

	/**
	 * 注册WebSocketHandler(WebSocket的核心处理器,可以监听指定端点),也可以设置SockJS回退选项
	 */
	void registerWebSocketHandlers(WebSocketHandlerRegistry registry);}

2、@EnableWebSocket注解

(1)注解引入一个配置类DelegatingWebSocketConfiguration.class

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebSocketConfiguration.class)
public @interface EnableWebSocket {
}

(2)DelegatingWebSocketConfiguration配置类会被容器自动加载,同时会注入容器中所有的WebSocketConfigurer实现到configurers中;同时registerWebSocketHandlers()方法会遍历configurers并回调所有WebSocketConfigurer的registerWebSocketHandlers()方法完成WebSocket的核心处理器的配置

@Configuration(proxyBeanMethods = false)
public class DelegatingWebSocketConfiguration extends WebSocketConfigurationSupport {

	private final List<WebSocketConfigurer> configurers = new ArrayList<>();


	@Autowired(required = false)
	public void setConfigurers(List<WebSocketConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addAll(configurers);
		}
	}


	@Override
	protected void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
		for (WebSocketConfigurer configurer : this.configurers) {
			configurer.registerWebSocketHandlers(registry);
		}
	}

}

在父类WebSocketConfigurationSupport中,被@Bean注释的webSocketHandlerMapping()开始初始化时,会从容器中获取一个默认的TaskScheduler(本配置类中使用@Bean注入的),然后通过initHandlerRegistry()创建一个ServletWebSocketHandlerRegistry,在initHandlerRegistry()方法中将创建的ServletWebSocketHandlerRegistry传递给registerWebSocketHandlers(),该方法就是由其子类DelegatingWebSocketConfiguration实现的,在上面的描述中可以看到出DelegatingWebSocketConfiguration 又将ServletWebSocketHandlerRegistry传递给了每一个用户自定义的WebSocketConfigurer的registerWebSocketHandlers()方法,用于配置WebSocketHandler

public class WebSocketConfigurationSupport {

	@Nullable
	private ServletWebSocketHandlerRegistry handlerRegistry;

	@Nullable
	private TaskScheduler scheduler;


	@Bean
	public HandlerMapping webSocketHandlerMapping(@Nullable TaskScheduler defaultSockJsTaskScheduler) {
		ServletWebSocketHandlerRegistry registry = initHandlerRegistry();
		if (registry.requiresTaskScheduler()) {
			TaskScheduler scheduler = defaultSockJsTaskScheduler;
			Assert.notNull(scheduler, "Expected default TaskScheduler bean");
			registry.setTaskScheduler(scheduler);
		}
		return registry.getHandlerMapping();
	}

	private ServletWebSocketHandlerRegistry initHandlerRegistry() {
		if (this.handlerRegistry == null) {
			this.handlerRegistry = new ServletWebSocketHandlerRegistry();
			registerWebSocketHandlers(this.handlerRegistry);
		}
		return this.handlerRegistry;
	}

	protected void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
	}

	@Bean
	@Nullable
	public TaskScheduler defaultSockJsTaskScheduler() {
		if (initHandlerRegistry().requiresTaskScheduler()) {
			ThreadPoolTaskScheduler threadPoolScheduler = new ThreadPoolTaskScheduler();
			threadPoolScheduler.setThreadNamePrefix("SockJS-");
			threadPoolScheduler.setPoolSize(Runtime.getRuntime().availableProcessors());
			threadPoolScheduler.setRemoveOnCancelPolicy(true);
			this.scheduler = threadPoolScheduler;
		}
		return this.scheduler;
	}
}

注意:如果项目其他地方需要使用TaskScheduler ,并且重复配置了一个TaskScheduler ,这里就会冲突

3、实现WebSocketConfigurer配置

我们可以在一个项目中配置多个WebSocketHandler用于处理不同端点的消息(类似Controller接口)

@Configuration
@EnableWebSocket
@ComponentScan(basePackages = "cn.edu1010.websocket.handler", useDefaultFilters = false, includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Component.class))
public class WebSocketConfig implements WebSocketConfigurer {

	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

	}
}

三、注册WebSocketHandler

1、WebSocketHandler消息处理器接口

public interface WebSocketHandler {

    //WebSocket连接建立成功之后调用
	void afterConnectionEstablished(WebSocketSession session) throws Exception;

    //新的WebSocket消息到达时调用
	void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception;

    //处理来自底层的WebSocket的消息传输错误
	void handleTransportError(WebSocketSession session, Throwable exception) throws Exception;

	 //WebSocket连接已被任何一方关闭,或者发生传输错误之后调用
	void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception;

	//是否支持分片消息
	boolean supportsPartialMessages();
}

可以实现WebSocketHandler接口,也可以继承AbstractWebSocketHandler类来创建WebSocketHandler实例

@Component
public class SpringSocketHandle extends AbstractWebSocketHandler {

	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		// TODO Auto-generated method stub
	}

	/**
	 * 文本消息体
	 */
	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		// TODO Auto-generated method stub
	}

	/**
	 * 二进制消息体
	 */
	@Override
	protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
		// TODO Auto-generated method stub
	}

	/**
	 * Pong 消息体
	 */
	@Override
	protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
		// TODO Auto-generated method stub
	}

	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		// TODO Auto-generated method stub
	}

	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
		// TODO Auto-generated method stub
	}
}

2、注册WebSocketHandler

在创建的WebSocketConfig中使用WebSocketHandlerRegistry注册SpringSocketHandle,并为其指定端点"/endpoint"。这里需要注意WebSocketHandlerRegistry .addHandler(WebSocketHandler webSocketHandler, String… paths)的第二个参数是一个字符串类型的参数列表,这就说明你可以为多个端点指定同样配置的WebSocketHandler处理

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
	@Autowired
	public SpringSocketHandle springSocketHandle;

	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
	   registry.addHandler(springSocketHandle, "/endpoint");
	}
}

四、配置WebSocketHandler

WebSocketHandlerRegistry.addHandler()方法注册WebSocketHandler之后会返回WebSocketHandlerRegistration用于配置WebSocketHandler

public interface WebSocketHandlerRegistration {
    //继续添加消息处理器
	WebSocketHandlerRegistration addHandler(WebSocketHandler handler, String... paths);
    //添加握手处理器,处理握手事件
	WebSocketHandlerRegistration setHandshakeHandler(HandshakeHandler handshakeHandler);
    //添加握手拦截器,可以在处理握手前和握手后处理一些业务逻辑
	WebSocketHandlerRegistration addInterceptors(HandshakeInterceptor... interceptors);
    //配置允许的浏览器跨源请求类型
	WebSocketHandlerRegistration setAllowedOrigins(String... origins);
    //配置允许的浏览器跨源请求类型
	WebSocketHandlerRegistration setAllowedOriginPatterns(String... originPatterns);
    //允许使用SockJS应急选项
	SockJsServiceRegistration withSockJS();
}

五、WebSocketMessage和WebSocketSession

1、WebSocketMessage

public interface WebSocketMessage<T> {

	/**
	 * 消息载荷
	 */
	T getPayload();

	/**
	 * 消息字节长度
	 */
	int getPayloadLength();

	/**
	 * 当org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()配置允许分片消息时,
	 * 如果当前消息是客户端本次送达消息的最后一部分时,该方法返回true。如果分片消息不可用或是被禁用,放回false
	 */
	boolean isLast();
}

2、WebSocketSession

public interface WebSocketSession extends Closeable {

	/**
	 * 会话标识
	 */
	String getId();

	/**
	 * WebSocket 连接的URI
	 */
	@Nullable
	URI getUri();

	/**
	 * 返回握手请求中使用的Headers
	 */
	HttpHeaders getHandshakeHeaders();

	/**
	 *返回WebSocke会话关联的属性。
	 *在服务端,可以使用org.springframework.web.socket.server.HandshakeInterceptor填充属性
	 *在客户端,可以使用org.springframework.web.socket.client.WebSocketClient的握手方法填充属性
	 */
	Map<String, Object> getAttributes();

	/**
	 * 返回一个包含已验证的用户名称的java.security.Principal实例,如果用户没有验证成功返回null
	 */
	@Nullable
	Principal getPrincipal();

	/**
	 * 返回请求接收方的地址
	 */
	@Nullable
	InetSocketAddress getLocalAddress();

	/**
	 * 返回客户端的地址
	 */
	@Nullable
	InetSocketAddress getRemoteAddress();

	/**
	 *返回约定的子协议,如果没有协议或是协议失败返回null
	 */
	@Nullable
	String getAcceptedProtocol();

	/**
	 * 配置一次接收文本消息最大值
	 */
	void setTextMessageSizeLimit(int messageSizeLimit);

	/**
	 * 获取一次接收文本消息最大值
	 */
	int getTextMessageSizeLimit();

	/**
	 * 配置一次接收二进制消息最大值
	 */
	void setBinaryMessageSizeLimit(int messageSizeLimit);

	/**
	 * 获取一次接收二进制消息最大值
	 */
	int getBinaryMessageSizeLimit();

	/**
	 * 获取约定的扩展
	 */
	List<WebSocketExtension> getExtensions();

	/**
	 * 发送消息,WebSocket会话底层协议不支持并发发送消息,因此发送必须是同步的。
	 * 保证信息发送同步进行,一种方法是使用org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator
	 * 包装WebSocketSession
	 */
	void sendMessage(WebSocketMessage<?> message) throws IOException;

	/**
	 * 底层连接是否打开
	 */
	boolean isOpen();

	/**
	 * 使用状态码1000关闭WebSocket连接
	 */
	@Override
	void close() throws IOException;

	/**
	 * 使用指定状态码WebSocket连接
	 */
	void close(CloseStatus status) throws IOException;
}
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot是一个用于创建独立、生产级别的Spring应用程序的框架。而J-IM是一款基于Netty实现的轻量级IM(即即时通讯)框架。 在Spring Boot集成J-IM可以实现以下功能: 1. 快速搭建IM服务器:Spring Boot的自动化配置和脚手架特性能够快速搭建J-IM服务器,简化了配置和部署的过程。 2. 支持高并发和大规模的用户连接:J-IM基于Netty实现,具有高性能和高并发的特点,能够支持大规模的用户连接和消息传输。 3. 支持多协议和多种API调用方式:J-IM支持TCP、WebSocket等多种协议,可以根据实际需求选择合适的协议进行通信。同时,J-IM还提供了多种API调用方式,方便开发者进行二次开发和定制。 4. 提供可扩展的消息处理机制:J-IM提供了可扩展的消息处理机制,可以根据业务需求自定义消息的处理逻辑,满足不同场景下的消息处理需求。 5. 提供完善的监控和运维功能:J-IM支持实时监控、在线用户管理和统计功能,可以方便地对IM服务器进行监控和运维。 6. 良好的兼容性和生态系统:Spring Boot作为一个广泛使用的框架,具有良好的兼容性,能够与各种数据库、缓存、消息队列等其他组件进行集成,形成完整的生态系统。 通过Spring Boot集成J-IM,可以快速搭建一个高性能、可扩展的IM服务器,方便开发者构建自己的即时通讯应用。同时,Spring Boot的自动化配置和脚手架特性也提供了更便捷的开发和部署流程,降低了开发和运维的成本。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豢龙先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值