WebSocket | Netty netty-websocket-spring-boot-starter

Netty netty-websocket-spring-boot-starter

  • 一、前言
  • 二、快速开始
    • 1. 引入pom坐标
    • 2. websocket实现
    • 3. 启动成功
  • 三、总结

一、前言

本文讲述 基于springboot + netty 实现websocket服务端搭建。

使用springboot 集成 netty-websocket-spring-boot-starter 来实现websocket

也有直接通过netty 代码方式实现的方式但是不推荐,传统方式暂时我还无法找到通过url的方式来进行路由区分的,需要每个业务场景定义一个端口。
netty代码方式实现地址:https://blog.csdn.net/qq825478739/article/details/126263050

需要了解netty的 请点击网址查看我总结的一些netty的介绍
netty介绍地址:还没完善后边不上

netty-websocket-spring-boot-starter gitee地址:https://gitee.com/Yeauty/netty-websocket-spring-boot-starter

二、快速开始

1. 引入pom坐标

	<dependency>
		<groupId>org.yeauty</groupId>
		<artifactId>netty-websocket-spring-boot-starter</artifactId>
		<version>0.9.5</version>
	</dependency>

2. websocket实现

/**
 * 当springboot 项目启动会通过自动装配 找到netty-websocket-spring-boot-starter 中META-INF 加载 NettyWebSocketAutoConfigure
 * 通过@EnableWebSocket -> @Import({NettyWebSocketSelector.class})
 * 在 NettyWebSocketSelector 中会创建  Bean ServerEndpointExporter 被Spring声明并使用
 *
 * ServerEndpointExporter 类通过Spring配置声明并被使用,
 * ServerEndpointExporter 将会去扫描带有@ServerEndpoint 注解的类注册成为一个WebSocket断电。
 * 所有的配置项都在这个@ServerEndpoint注解属性中  ( 如:@ServerEndpoint("/ws") )
 * 
 */
 //TODO 不需要加Spring的注解加载, 多例的,每次请求过来都会创建一个新的可以通过。无参构造查看
// port 默认80  host默认 0.0.0.0
@ServerEndpoint(path = "/ws/{arg}",port = "80",host = "0.0.0.0")
public class MyWebSocket {

    public MyWebSocket() {
        System.out.println("通过这里可以看到 每次请求过来都会创建");
    }

    /**
     * 当有新的连接进入时,对该方法进行回调 注入参数的类型  一般用不是 可以去掉
     *
     * @param session
     * @param headers
     * @param req
     * @param reqMap
     * @param arg
     * @param pathMap
     */
    @BeforeHandshake
    public void handshake(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable String arg, @PathVariable Map pathMap){
        session.setSubprotocols("stomp");
        if (!"ok".equals(req)){
            System.out.println("Authentication failed!");
            session.close();
        }
    }

    /**
     * 当有新的WebSocket连接完成时,会调用这个方法
     *
     * @param session
     * @param headers
     * @param req
     * @param reqMap
     * @param arg
     * @param pathMap
     */
    @OnOpen
    public void onOpen(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable String arg, @PathVariable Map pathMap){
        System.out.println("new connection");
        System.out.println(req);
    }

    /**
     * 当有WebSocket 关闭连接时 调用
     *
     * @param session
     * @throws IOException
     */
    @OnClose
    public void onClose(Session session) throws IOException {
       System.out.println("one connection closed"); 
    }

    /**
     * 当有WebSocket 抛出异常 调用
     *
     * @param session
     * @param throwable
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }


    /**
     * 当接收到字符串消息时,调用
     *  message 请求参数 只能用字符串接收否则会报错 类型转换异常
     *
     * @param session
     * @param message
     */
    @OnMessage
    public void onMessage(Session session, String message) {
        System.out.println(message);

        //TODO 发送消息
        session.sendText("Hello Netty!");
    }

    /**
     * 当接收到二进制消息时 调用
     *
     * @param session
     * @param bytes
     */
    @OnBinary
    public void onBinary(Session session, byte[] bytes) {
        for (byte b : bytes) {
            System.out.println(b);
        }
        session.sendBinary(bytes); 
    }

    /**
     * 当接收到Netty的事件时 调用
     *
     * @param session
     * @param evt
     */
    @OnEvent
    public void onEvent(Session session, Object evt) {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            switch (idleStateEvent.state()) {
                case READER_IDLE:
                    System.out.println("read idle");
                    break;
                case WRITER_IDLE:
                    System.out.println("write idle");
                    break;
                case ALL_IDLE:
                    System.out.println("all idle");
                    break;
                default:
                    break;
            }
        }
    }

}

3. 启动成功

WebSocket | Netty netty-websocket-spring-boot-starter_第1张图片

三、总结

在使用过程中遇到一个问题 ,当 onMessage 方法 接收参数用对象接收的话会报错。
我以为@RequestParam


错误使用方式
WebSocket | Netty netty-websocket-spring-boot-starter_第2张图片
在这里插入图片描述
将对象改成字符串接收。再用Json转换把。

你可能感兴趣的:(SpringBoot,spring,websocket,java,1024程序员节)