Spring和Web套接字:进行身份验证并关闭页面更改/关闭连接

时间:2018-10-31 13:56:01

标签: java angularjs spring spring-security websocket

第一时间,我在spring项目中使用了web socket。 这是配置:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Autowired 
    private Environment env;
    public static final String TOPICS_ROOT_PATH = "ws.topic";
    public static final String APPLICATION_PREFIX_PATH = "ws.prefix_path";
    public static final String SOCKET_PATH = "ws.socket_path";

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker(env.getRequiredProperty(TOPICS_ROOT_PATH));
        config.setApplicationDestinationPrefixes(env.getRequiredProperty(APPLICATION_PREFIX_PATH));
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint(env.getRequiredProperty(SOCKET_PATH));
        registry.addEndpoint(env.getRequiredProperty(SOCKET_PATH)).withSockJS();
    }
}

然后我在angularjs中配置了一个工厂来管理Web套接字:

angular.module('myApp').factory(
        'wsService',
        ['$rootScope', '$timeout', function ($rootScope, $timeout) {
                const RETRY_TIMEOUT = 10000;
                const WEBSOCKET_PATH = './wsendpoint';
                const APP_PATH = '/app';

                var wsClient = {
                        wsClient: this,
                        stompClient: null,
                        socket: null,
                        subscriptions: new Map(),

                        connect: function () {
                            var url = WEBSOCKET_PATH;
                            wsClient.socket = new SockJS(url);
                            wsClient.stompClient = Stomp.over(wsClient.socket);
                            wsClient.stompClient.debug = null;

                            const connectCallback = function (frame) {
                                $rootScope.$broadcast('STOMP_CONNECTED', {});
                            };

                            const errorCallback = function () {
                                $timeout( function(){
                                    wsClient.connect();
                                }, RETRY_TIMEOUT);
                            };

                            wsClient.stompClient.connect({}, connectCallback, errorCallback);
                        },

                        isConnected: function () {
                            return wsClient.stompClient.connected;
                        },

                        send: function (destination, headers, payload) {
                            if (wsClient.isConnected()) {
                                console.log("Sending message to " + destination);
                                wsClient.stompClient.send(destination, headers, payload);
                            } else {
                                $rootScope.$on('STOMP_CONNECTED', function () {
                                    console.log("Sending message to " + destination);
                                    wsClient.stompClient.send(destination, headers, payload);
                                });
                            }
                        },

                        unsubscribe: function (topic) {
                            if (wsClient.subscriptions.get(topic)) {
                                wsClient.subscriptions.get(topic).unsubscribe();
                                wsClient.subscriptions.delete(topic);
                            }
                        },

                        subscribe: function (topicName, callback) {
                            subscribeWhenConnected(topicName, callback);
                        }        
                };

                function subscribeWhenConnected(topicName, callback) {
                    console.log("Subscribing to topic: " + topicName);
                    if (wsClient.isConnected()) {
                        subscribeAndRunJob(topicName, callback);
                    } else {
                        $rootScope.$on('STOMP_CONNECTED', function () {
                            subscribeAndRunJob(topicName, callback);
                        });
                    }
                };

                function subscribeAndRunJob(topicName, callback) {        
                    const sub = wsClient.stompClient.subscribe(topicName, callback);
                    wsClient.subscriptions.set(topicName, sub);        
                } 

                wsClient.connect();
                return wsClient;

        }]
)
.run(function () {
    console.debug("Web Socket is connected");
});

要从服务器发送到客户端,我使用SimpMessagingTemplate和方法convertAndSend。 现在我有两个问题:

  1. 这些网络套接字只能由登录用户访问,以便通过身份验证?
  2. 当连接断开或用户更改或关闭打开套接字的页面时,如何在服务器上停止套接字?目前,我使用:

    $ scope。$ on('$ locationChangeStart',function(event,next,current){         wsService.unsubscribe(wsTopic);     });

谢谢

0 个答案:

没有答案