开发者

spring配置websocket的完整流程

目录
  • 一、添加依赖 (build.gradle.kts 或 pom.XML)
  • 二、基础 WebSocket 配置
    • 1. 启用 WebSocket 支持
  • 三、核心组件实现
    • 1. WebSocket 消息处理器
    • 2. 握手拦截器(安全校验)
  • 四、客户端连接示例(JavaScript + Kotlin)
    • 1. Web 前端连接
    • 2. android 客户端(Kotlin)
  • 五、高级配置
    • 1. 消息压缩配置
    • 2. 集群支持(Redis 广播)
  • 六、监控与调试
    • 1. 端点监控
    • 2. 日志配置 (logback-spring.xml)
  • 七、常见问题解决方案
    • 八、安全增强建议
      • 九、性能测试建议
        • 总结

          在 Spring Boot 中使用 Kotlin 配置 WebSocket 的完整流程如下(包含基础配置、安全增强和性能优化):

          一、添加依赖 (build.gradle.kts 或 pom.xml)

          // build.gradle.kts
          dependencies {
              implementation("org.springframework.boot:spring-boot-starter-websocket")
              implementation("com.fasterxml.jackson.module:jackson-module-kotlin") // jsON 支持
          }
          

          二、基础 WebSocket 配置

          1. 启用 WebSocket 支持

          @Configuration
          @EnableWebhttp://www.devze.comSocket
          class WebSocketConfig : WebSocketConfigurer {
          
              @Autowired
              lateinit var myWebSocketHandler: MyWebSocketHandler
          
              @Autowired
              lateinit var handshakeInterceptor: AuthHandshakeInterceptor
          
              override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
                  registry.addHandler(myWebSocketHandler, "/ws")
                      .addInterceptors(handshakeInterceptor)
                      .setAllowedOrigins("*") // 生产环境应限制域名
              }
          }
          

          三、核心组件实现

          1. WebSocket 消息处理器

          @Component
          class MyWebSocketHandler : TextWebSocketHandler() {
          
              private val sessions = ConcurrentHashMap<String, WebSocketSession>()
              private val logger = LoggerFactory.getLogger(this::class.java)
          
              // 连接建立
              override fun afterConnectionEstablished(session: WebSocketSession) {
                  val userId = session.attributes["userId"] as? String
                  userId?.let {
                      sessions[it] = session
                      logger.info("User $it connected, total: ${sessions.size}")
                  } ?: run {
                      session.close(CloseStatus.BAD_DATA)
                  }
              }
          
              // 处理文本消息
              override fun handleTextMessage(session: WebSocketSession, message: TextMessage) {
                  val payload = message.payload
                  logger.debug("Received message: $payload")
                  
                  // 示例:广播消息
                  sessions.values.forEach { 
                      it.sendMessage(TextMessage("Broadcast: $payload"))
                  }
              }
          
              // 连接关闭
              override fun afterConnectionClosed(session: WebSocketSession, status: CloseStatus) {
                  sessions.values.remove(session)
                  logger.info("Connection closed: ${status.reason}")
              }
          
              // 主动推送方法
              fun sendToUser(userId: String, message: String) {
                  sessions[userId]?.sendMessage(TextMessage(message))
              }
          }
          

          2. 握手拦截器(安全校验)

          @Component
          class AuthHandshakeInterceptor : HandshakeInterceptor {
          
              override fun beforeHandshake(
                  request: ServerHttpRequest,
                  response: ServerHttpResponse,
                  wsHandler: WebSocketHandler,
                  attributes: MutableMap<String, Any>
              ): Boolean {
                  // 1. 校验 Token
                  val token = request.uri.query?.split("token=")?.get(1)
                  if (!validateToken(token)) {
                      response.statusCode = HttpStatus.UNAUTHORIZED
                      return false
                  }
          
                  // 2. 获取用户信息
                  val userId = parseUserIdFromToken(token)
                  attributes["userId"] = userId
                  
                  // 3. 记录握手日志
                  logHandshake(request.remoteAddress?.hostName)
                  return true
              }
          
              private fun validateToken(token: String?): Boolean {
                  // 实现 JWT 校验逻辑
                  return token?.startsWith("valid_") == true
              }
          }
          

          四、客户端连接示例(javascript + Kotlin)

          1. Web 前端连接

          const socket = new WebSocket(`ws://${location.host}/ws?token=valid_123`);
          
          socket.onmessage = (event) => {
            console.log('Received:', event.data);
          };
          
          // 发送心跳包保持连接
          setInterval(() => {
            socket.send(JSON.stringify({ type: "heartbeat" }));
          }, 30000);
          

          2. Android 客户端(Kotlin)

          class WebSocketClient(url: String) : WebSocketListener() {
              private val client = OkHttpClient()
              private var ws: WebSocket? = null
          
              init {
                  val request = Request.Builder().url(url).build()
                  ws = client.newWebSocket(request, this)
              }
          
              override fun onMessage(webSocket: WebSocket, text: String) {
                  println("Received: $text")
              }
          
              fun sendMessage(msg: String) {
                  ws?.send(msg)
              }
          }
          

          五、高级配置

          1. 消息压缩配置

          @Bean
          fun webSocketContainer(): ServletServerContainerFactoryBean {
              return ServletServerContainerFactoryBean().apply {
                  setMaxTextMessageBufferSize(8192)
                  setMaxBinaryMessageBufferSize(8192)
                  setAsyncSendTimeout(30000L) // 30秒异步发送超时
              }
          }
          

          2. 集群支持(Redis 广播)

          @Configuration
          @EnableRedisRepositories
          class RedisPubSubConfig {
          
              @Bean
              fun redisTemplate(connectionFactory: RedisConnectionFactory): RedisTemplate<String, String> {
                  return RedisTemplate<String, String>().apply {
                      setConnectionFactory(connectionFactory)
                  }
              }
          
              @Bean
              fun topicListenerAdapter(handler: MessageListener): ChannelTopic {
                  return ChannelTopic("websocket-messages")
              }
          }
          

          六、监控与调试

          1. 端点监控

          @RestController
          class WebSocketMetricsController(
              private val handler: MyWebSocketHandler
          ) {
          
              @GetMapping("/metrics/websocket")
              fun getMetrics(): Map<String, Any> {
                  return mapOf(
                      "activeConnections" to handler.getSessionCount(),
                      "jslastMessageTime" to handler.getLastActivity()
                  )
              }
          }
          

          2. 日志配置 (logback-spring.xml)

          <logger name="org.springframework.web.socket" level="DEBUG"/>
          <logger name="com.example.websocket" level="TRACE"/>
          

          七、常见问题解决方案

          问题现象解决方案
          连接频繁断开添加心跳机制,调整 setAsyncSendTimeout
          跨域失败精确配置 .setAllowedOrigins("https://your-domain.com")
          消息顺序错乱使用 @SendToUser(destination = "/queue", broadcast = false) 点对点发送
          内存泄漏定期检查 sessions Map,添加连接超时清理逻辑
          高并发时性能下降启用异步消息处理,使用 Redis Pub/Sub 分流消息

          八、安全增强建议

          • 启用 WSS 协议

            # Nginx 配置示例
            location /ws {
                proxy_pass http://backend;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header X-Real-IP $remote_addr;
                proxy_ssl_protocols TLSv1.2 TLSv1.3;
            }
            
          • 限流防护

            @Bean
            fun webSocketRateLimiter(): WebSocketHandlerDecoratorFactory {
                return object : WebSocketHandlerDecoratorFactory {
                    override fun decorate(handler: WebSocketHandler): WebSocketHandler {
                        val r编程客栈ateLimiter = RateLimiter.create(100) // 100次/秒
                        return object : WebSocketHandlerDecorator(handler) {
                            override fun handleMessage(session: WebSocketSession, message: WebSocketMessage<*>php;) {
                                if (!rateLimiter.tryAcquire()) {
                                    session.close(CloseStatus.POLICY_VIOLATION)
                                    return
                                }
                                super.handleMessage(session, message)
                            }
                        }
                    }
                }
            }
            

          九、性能测试建议

          • 使用 JMeter 压测

            <!-- WebSocket 压测计划示例 -->
            <WebSocketSampler>
              <connectTime>5000</connectTime>
              <responseTimeout>10000</responseTimeout>
              <payload>{ "type": "stress", "data": "test" }</payload>
            </WebSocketSampjavascriptler>
            
          • 监控指标

            • 单节点最大连接数

            • 消息往返延迟 (RTT)

            • 内存占用增长率

          通过以上配置,可以实现一个高性能、安全可靠的企业级 WebSocket 服务,支持从开发到生产的全生命周期管理。

          总结

          到此这篇关于spring配置websocket的文章就介绍到这了,更多相关spring配置websocket内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

          0

          上一篇:

          下一篇:

          精彩评论

          暂无评论...
          验证码 换一张
          取 消

          最新开发

          开发排行榜