Spring Boot Websockets / SockJS / STOMP客户端+服务器最小示例

时间:2018-10-24 09:01:38

标签: spring-boot websocket kotlin stomp

最好在Kotlin中最简单的用于Client and Server的Spring Boot示例是什么?

1 个答案:

答案 0 :(得分:0)

服务器

build.gradle:

compile 'org.springframework:spring-websocket:5.1.1.RELEASE'
compile 'org.springframework:spring-messaging:5.1.1.RELEASE'

server.kt:

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
import org.springframework.context.annotation.Configuration
import org.springframework.messaging.handler.annotation.MessageMapping
import org.springframework.messaging.handler.annotation.SendTo
import org.springframework.messaging.simp.config.MessageBrokerRegistry
import org.springframework.stereotype.Controller
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
import org.springframework.web.socket.config.annotation.StompEndpointRegistry

fun main(args: Array<String>) {
    SpringApplication.run(Application::class.java, *args)
}

@SpringBootApplication
class Application : SpringBootServletInitializer() {
    override fun configure(builder: SpringApplicationBuilder): SpringApplicationBuilder {
        return builder.apply {
            builder.sources(Application::class.java)
        }
    }
}

@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfig : AbstractWebSocketMessageBrokerConfigurer() {

    override fun configureMessageBroker(config: MessageBrokerRegistry) {
        config.enableSimpleBroker("/topic")
        config.setApplicationDestinationPrefixes("/app")
    }

    override fun registerStompEndpoints(config: StompEndpointRegistry) {
        config.addEndpoint("/ws")
                .setAllowedOrigins("*")
                .withSockJS()
    }
}

@Controller
class Controller {
    @MessageMapping("/my/server/method")
    @SendTo("/my/room/where/client/subscribed")
    fun myservermethod(data: Any): Any {
        // data will be "some data as string"

        // todo to something useful
        return mapOf("hello" to "world")
    }
}

客户

build.gradle:

compile 'org.springframework:spring-websocket:5.1.1.RELEASE'
compile 'org.springframework:spring-messaging:5.1.1.RELEASE'
compile 'org.glassfish.tyrus.bundles:tyrus-standalone-client-jdk:1.14'

client.kt:

import org.springframework.messaging.converter.MappingJackson2MessageConverter
import org.springframework.messaging.simp.stomp.*
import org.springframework.web.socket.client.standard.StandardWebSocketClient
import org.springframework.web.socket.messaging.WebSocketStompClient
import org.springframework.web.socket.sockjs.client.SockJsClient
import org.springframework.web.socket.sockjs.client.WebSocketTransport
import java.lang.reflect.Type

fun main(args: Array<String>) {
    val webSocketTransport = WebSocketTransport(StandardWebSocketClient())
    val sockJsClient = SockJsClient(listOf(webSocketTransport))
    val stompClient = WebSocketStompClient(sockJsClient).apply {
        messageConverter = MappingJackson2MessageConverter()
    }

    val sessionHandler = MyStompSessionHandler()

    stompClient.connect("http://localhost:8080/ws", sessionHandler)

    while (true) Thread.sleep(Long.MAX_VALUE)
}

class MyStompSessionHandler : StompSessionHandlerAdapter() {
    override fun handleException(session: StompSession, command: StompCommand?, headers: StompHeaders, payload: ByteArray, exception: Throwable) {
        println("handleException $exception")
    }

    override fun handleTransportError(session: StompSession, exception: Throwable) {
        println("handleTransportError $exception")
    }

    override fun handleFrame(headers: StompHeaders, payload: Any?) {
        println("handleFrame: $payload")
    }

    override fun afterConnected(session: StompSession, connectedHeaders: StompHeaders) {
        session.subscribe("/my/room/where/client/subscribed", object : StompFrameHandler {
            override fun handleFrame(headers: StompHeaders, payload: Any?) {
                // payload will be mapOf("hello" to "world")
                println(payload)
            }

            override fun getPayloadType(headers: StompHeaders): Type {
                return Any::class.java
            }
        })

        session.send("/app/my/server/method", "some data as string")
    }
}