SpringBoot项目集成WebSocket

前言

最近项目中需要集成websocket,推送消息到浏览器,下面简单说下集成的流程,因为开发android习惯了使用kotlin,所以服务端也改成了用kotlin来写,因为kotlin写起来代码来是真的舒服,下面的代码以kotlin为例,java代码也是一样的

过程
  1. 添加依赖

    1
    2
    3
    4
    <dependency>  
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
  2. 启用websocket配置

    1
    2
    3
    4
    5
    @Configuration
    class WebSocketConfig {
    @Bean
    fun serverEndpointExporter(): ServerEndpointExporter = ServerEndpointExporter()
    }
  3. 编写ws服务

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    /**
    * @apiNote : websocket服务端
    * @author : jinsc create at 2022/7/25 10:05
    */
    /**@ServerEndpoint 注解这是一个类层次的注解,它的功能主要是将目前的类定义成一个 websocket 服务器端。注解的值将被用于监听用户连接的终端访问 URL 地址,客户端可以通过这个 URL 来连接到 WebSocket 服务器端 */
    @Slf4j
    @ServerEndpoint("/sire/socket")
    @Component
    class WebSocketService {



    @OnOpen
    fun onOpen(session: Session) {
    clients[session.id] = session
    atomicInteger.incrementAndGet()
    log.info("新的连接:{},当前在线人数:{}", session.id, atomicInteger.get())
    }

    @OnClose
    fun onClose(session: Session) {
    clients.remove(session.id)
    atomicInteger.decrementAndGet()
    log.info("连接关闭:{},当前在线人数:{}", session.id, atomicInteger.get())
    }

    @OnMessage
    fun onMessage(message: String, session: Session) {
    log.info("收到客户端:{} 的消息:{}", session.id, message)
    session.asyncRemote.sendText(message)
    }

    @OnError
    fun onError(session: Session, throwable: Throwable) {
    log.error("ws发生错误:", throwable)
    }


    companion object {

    /**
    * 存储在线连接数
    */
    var atomicInteger = AtomicInteger(0)

    /**
    * 存储所有的session
    */
    var clients: ConcurrentHashMap<String, Session> = ConcurrentHashMap()

    /**
    * 发送消息
    * @param message 消息内容
    */
    fun sendToMsg(message: String) {
    log.info("当前在线人数:{}", atomicInteger.get())
    clients.values.forEach {
    it.asyncRemote.sendText(message)
    }
    }
    }
    }

    其实很简单,只需要复写四个方法,具体就不说了,见名知意

  4. 测试

    1
    WebSocketService.sendToMsg("hello world"))

    因为上文中WebSocketService.sendToMsg方法是写在伴生对象里的,这是kotlin中static方法的写法,就类似java的public static方法,所以外部可以直接调用,不需要再注入