SoFunction
Updated on 2025-05-23

The complete process of spring configuring websocket

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 inspectionsessionsMap, 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&lt;*&gt;) {
                        if (!()) {
                            (CloseStatus.POLICY_VIOLATION)
                            return
                        }
                        (session, message)
                    }
                }
            }
        }
    }
    

9. Performance testing suggestions

  • Pressure test with JMeter

    &lt;!-- WebSocket Example of stress test plan --&gt;
    &lt;WebSocketSampler&gt;
      &lt;connectTime&gt;5000&lt;/connectTime&gt;
      &lt;responseTimeout&gt;10000&lt;/responseTimeout&gt;
      &lt;payload&gt;{ "type": "stress", "data": "test" }&lt;/payload&gt;
    &lt;/WebSocketSampler&gt;
    
  • 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!