Сервер
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")
}
}