The complete process of configuring WebSocket with Kotlin in Spring Boot is as follows (including basic configuration, security enhancement, and performance optimization):
1. Add dependencies (or)
// dependencies { implementation(":spring-boot-starter-websocket") implementation(":jackson-module-kotlin") // JSON support}
2. Basic WebSocket Configuration
1. Enable WebSocket Support
@Configuration @EnableWebSocket class WebSocketConfig : WebSocketConfigurer { @Autowired lateinit var myWebSocketHandler: MyWebSocketHandler @Autowired lateinit var handshakeInterceptor: AuthHandshakeInterceptor override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) { (myWebSocketHandler, "/ws") .addInterceptors(handshakeInterceptor) .setAllowedOrigins("*") // Domain names should be restricted in the production environment } }
Implementation of core components
1. WebSocket Message Processor
@Component class MyWebSocketHandler : TextWebSocketHandler() { private val sessions = ConcurrentHashMap<String, WebSocketSession>() private val logger = (this::) // Connection establishment override fun afterConnectionEstablished(session: WebSocketSession) { val userId = ["userId"] as? String userId?.let { sessions[it] = session ("User $it connected, total: ${}") } ?: run { (CloseStatus.BAD_DATA) } } // Process text messages override fun handleTextMessage(session: WebSocketSession, message: TextMessage) { val payload = ("Received message: $payload") // Example: Broadcast message { (TextMessage("Broadcast: $payload")) } } // Connection closed override fun afterConnectionClosed(session: WebSocketSession, status: CloseStatus) { (session) ("Connection closed: ${}") } // Active push method fun sendToUser(userId: String, message: String) { sessions[userId]?.sendMessage(TextMessage(message)) } }
2. Handshake Interceptor (Safety Verification)
@Component class AuthHandshakeInterceptor : HandshakeInterceptor { override fun beforeHandshake( request: ServerHttpRequest, response: ServerHttpResponse, wsHandler: WebSocketHandler, attributes: MutableMap<String, Any> ): Boolean { // 1. Verify Token val token = ?.split("token=")?.get(1) if (!validateToken(token)) { = return false } // 2. Obtain user information val userId = parseUserIdFromToken(token) attributes["userId"] = userId // 3. Record the handshake log logHandshake(?.hostName) return true } private fun validateToken(token: String?): Boolean { // Implement JWT verification logic return token?.startsWith("valid_") == true } }
4. Client connection example (JavaScript + Kotlin)
1. Web front-end connection
const socket = new WebSocket(`ws://${}/ws?token=valid_123`); = (event) => { ('Received:', ); }; // Send heartbeat packets to keep connectedsetInterval(() => { (({ type: "heartbeat" })); }, 30000);
2. Android Client (Kotlin)
class WebSocketClient(url: String) : WebSocketListener() { private val client = OkHttpClient() private var ws: WebSocket? = null init { val request = ().url(url).build() ws = (request, this) } override fun onMessage(webSocket: WebSocket, text: String) { println("Received: $text") } fun sendMessage(msg: String) { ws?.send(msg) } }
V. Advanced configuration
1. Message compression configuration
@Bean fun webSocketContainer(): ServletServerContainerFactoryBean { return ServletServerContainerFactoryBean().apply { setMaxTextMessageBufferSize(8192) setMaxBinaryMessageBufferSize(8192) setAsyncSendTimeout(30000L) // 30 seconds asynchronous sending timeout } }
2. Cluster Support (Redis Broadcast)
@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") } }
6. Monitoring and debugging
1. Endpoint monitoring
@RestController class WebSocketMetricsController( private val handler: MyWebSocketHandler ) { @GetMapping("/metrics/websocket") fun getMetrics(): Map<String, Any> { return mapOf( "activeConnections" to (), "lastMessageTime" to () ) } }
2. Log configuration (
)
<logger name="" level="DEBUG"/> <logger name="" level="TRACE"/>
7. Frequently Asked Questions
Problem phenomenon | Solution |
---|---|
Frequent disconnection of connection | Add heartbeat mechanism and adjustsetAsyncSendTimeout
|
Cross-domain failure | Precise configuration.setAllowedOrigins("")
|
Message order is incorrect | use@SendToUser(destination = "/queue", broadcast = false) Point-to-point sending |
Memory leak | Regular inspectionsessions Map, add connection timeout cleaning logic |
Performance degradation in high concurrency | Enable asynchronous message processing, use Redis Pub/Sub to shunt messages |
8. Safety enhancement suggestions
-
Enable the WSS protocol:
#Nginx configuration examplelocation /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; }
-
Current limit protection:
@Bean fun webSocketRateLimiter(): WebSocketHandlerDecoratorFactory { return object : WebSocketHandlerDecoratorFactory { override fun decorate(handler: WebSocketHandler): WebSocketHandler { val rateLimiter = (100) // 100 times/second return object : WebSocketHandlerDecorator(handler) { override fun handleMessage(session: WebSocketSession, message: WebSocketMessage<*>) { if (!()) { (CloseStatus.POLICY_VIOLATION) return } (session, message) } } } } }
9. Performance testing suggestions
-
Pressure test with JMeter:
<!-- WebSocket Example of stress test plan --> <WebSocketSampler> <connectTime>5000</connectTime> <responseTimeout>10000</responseTimeout> <payload>{ "type": "stress", "data": "test" }</payload> </WebSocketSampler>
Monitoring indicators:
• Maximum number of connections for single nodes
• Message round trip delay (RTT)
• Memory usage growth rate
Through the above configuration, a high-performance, safe and reliable enterprise-level WebSocket service can be realized, supporting the full life cycle management from development to production.
Summarize
This is the end of this article about spring configuring websocket. For more related spring configuring websocket content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!