• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

springBoot和Websocket(tomcat/netty)

互联网 diligentman 1周前 (01-14) 9次浏览

基于web服务器的websocket

  • pom
	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-websocket</artifactId>
		</dependency>
		
  • 使用
    • 注入ServerEndpointExporter
	@Bean
	public ServerEndpointExporter serverEndpointExporter() {
		return new ServerEndpointExporter();
	}
	
    • 声明端口


@ServerEndpoint("/webim/{userid}")
@Slf4j
public class WebSocketEndpoint {

  

	@OnOpen
	public void open(@PathParam("userid") String userid, Session session){
	
	}
	
	@OnClose
	public void close(@PathParam("userid") String userid, Session session){
		log.info("on close : " + userid);
	}
	
	@OnError
	public void error(@PathParam("userid") String userid, Session session, Throwable error){
		log.info("on error : " + userid);
	}
	
	@OnMessage
	public void handleMessage(@PathParam("userid") String userid, Session session, String message) throws IOException {
		log.info(userid + " on message :" )
	}

}

基于netty的websocket

  • 推荐:https://gitee.com/Yeauty/netty-websocket-spring-boot-starter

代码解读

在spring.factories中定义了需要加载的配置项:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.yeauty.autoconfigure.NettyWebSocketAutoConfigure

在配置项中,使用了注解@EnableWebSocket,所以我们可以通过@EnableWebSocket来定义我们的websocket server

@EnableWebSocket
public class NettyWebSocketAutoConfigure {
}

EnableWebSocket通过Import的方式又加载了NettyWebSocketSelector,并且在里面创建了一个ServerEndpointExporter,这是整个服务的核心类。
ServerEndpointExporter主要做了以下工作:

  • 完成了websocket服务地址和netty server实例的对应并且缓存。注意,整个实例是spring的代理类。
//ServerEndpointExporter.java
//可以创建多个websocket服务
 private final Map<InetSocketAddress, WebsocketServer> addressWebsocketServerMap = new HashMap<>();
 

那么,addressWebsocketServerMap 又是怎么添加上的?

//继承ApplicationObjectSupport就可以通过getApplicationContext()取到上下文,从而取到对应的代理类
public class ServerEndpointExporter extends ApplicationObjectSupport implements SmartInitializingSingleton, BeanFactoryAware {
    protected void registerEndpoints() {
    // 通过ServerEndpoint取到SpringContext中的ServerEndpoint代理实例。
        Set<Class<?>> endpointClasses = new LinkedHashSet<>();

        ApplicationContext context = getApplicationContext();
        if (context != null) {
            String[] endpointBeanNames = context.getBeanNamesForAnnotation(ServerEndpoint.class);
            for (String beanName : endpointBeanNames) {
                endpointClasses.add(context.getType(beanName));
            }
        }

        for (Class<?> endpointClass : endpointClasses) {
            registerEndpoint(endpointClass);
        }
        //调用了WebsocketServer的init
        init();
    }
    ....
    }

WebsocketServer在init方法中启动了netty server。并且添加了一个HttpServerHandler,在read方法中完成了消息的读取、发送、握手等操作。

HttpServerHandler.java
HttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> 

创建websocket需要注意的事项

  1. 安全性:只有系统用户可以连接,因此,在握手时需要校验身份。
  2. 重连机制
{{o.name}}


{{m.name}}


喜欢 (0)