天天看點

spring-boot項目整合socket同時啟用stomp模式

1.在項目pom檔案中配置

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>           

2.建立user

public class User implements Principal {

    private final String name;

    public User(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

}
           

3.建立ChannelInterceptor

@Component
public class ChannelInterceptor extends ChannelInterceptorAdapter {


    /**
     * 擷取包含在stomp中的使用者資訊
     */
    @SuppressWarnings("rawtypes")
    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        if (StompCommand.CONNECT.equals(accessor.getCommand())) {
            Object raw = message.getHeaders().get(SimpMessageHeaderAccessor.NATIVE_HEADERS);
            if (raw instanceof Map) {
                Object name = ((Map) raw).get("name");
                if (name instanceof LinkedList) {
                    // 設定目前通路器的認證使用者
                    accessor.setUser(new User(((LinkedList) name).get(0).toString()));
                }
            }
        }
        return message;
    }

}           

4.建立WebSocketConfig

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/market");
        registry.setApplicationDestinationPrefixes("/req");
        registry.setPreservePublishOrder(true);
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(new ChannelInterceptor());
    }

    /**
     *
     * @Title: createUserInterceptor
     * @Description: 将用戶端管道攔截器加入spring ioc容器
     * @return
     */
    @Bean
    public ChannelInterceptor createUserInterceptor() {
        return new ChannelInterceptor();
    }


}           

5.使用stomp

在所需要操作業務對象中導入一下代碼

@Autowired
 public SimpMessagingTemplate simpMessagingTemplate;
    @PostConstruct
    public void init() {
        simpMessagingTemplate.setMessageConverter(new SimpleMessageConverter());
    }           

需要将資料推送到前台的代碼中添加

simpMessagingTemplate.convertAndSend("/market/demo", "hello word!");           

6.前端代碼

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>WebSocket</title>
</head>
<body onload="disconnect()">
<div>
    <div>
        <button id="connect" onclick="connect();">連接配接</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">斷開連接配接</button>
    </div>
</div>
<script src="https://d1fxtkz8shb9d2.cloudfront.net/sockjs-0.3.4.min.js"></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="./protobuf.js"></script>


<script type="text/javascript">
    let stompClient = null;

    function setConnected(connected) {
        document.getElementById('connect').disabled = connected;
        document.getElementById('disconnect').disabled = !connected;
        $('#response1').html('');
    
    }

    function connect() {
        let socket = new SockJS('http://127.0.0.1:8080/ws');
        stompClient = Stomp.over(socket);
        stompClient.connect({
            name: 'TEST' // 攜帶用戶端資訊
        }, function(frame) {
            setConnected(true);
            var depth =stompClient.subscribe('/market/demo', function(respnose){
                $('#response1').html("stomp:"+respnose.body);
            });
        });
    }
    function disconnect() {
        if (stompClient != null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("斷開連接配接");

    }
</script>
</body>
</html>           

7.如有疑問請在文章評論處評論

繼續閱讀