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)!
精彩评论