第一时间,我在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
。
现在我有两个问题:
当连接断开或用户更改或关闭打开套接字的页面时,如何在服务器上停止套接字?目前,我使用:
$ scope。$ on('$ locationChangeStart',function(event,next,current){ wsService.unsubscribe(wsTopic); });
谢谢