Spring WebSocketMessageBrokerConfigurer с Artemis 2.6.3 Multicast (тема) не работает - PullRequest
0 голосов
/ 30 сентября 2018

Адрес и очередь передачи Artemis не имеют ожидаемого поведения.Моя идея заключается в создании групп или специальных сообщений для пользователя, которые могут иметь несколько сеансов веб-сокетов (веб, Android и т. Д.).Сервер опубликует уведомление на адрес многоадресной рассылки artemis, и все подписчики должны получить уведомление.В текущем сценарии я просто заставляю пользователя 'luislaves00' и создаю более одного сеанса.В Артемисе я вижу 2 потребителей (не знаю, как работает Message Broker Relay из весны), но потребители ведут себя как круговой прием, а не как подписчик-издатель.С брокером в памяти от Spring он работает нормально, но он не долговечен, поэтому, когда нет подключенного абонента, сообщения отбрасываются.Вот код, который я использую:

Клиентская часть:

function connect() {
    var socket = new SockJS('/notification-websocket');
    stompClient = Stomp.over(socket);
    var headers = {
        // todo: server will handle this logic
        'client-id': 'luisalves00',
        'durable-subscription-name': 'luisalves00',
        'id' : 'luisalves00'
    };
    stompClient.connect(headers, function(frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        // todo: server will handle this logic
        stompClient.subscribe('/topic/notification/username' + 'luisalves00', function(notification) {
            showNotification(JSON.parse(notification.body).content);
        }, headers);
    });
}

Конфигурация Broker Relay:

public void configureMessageBroker(MessageBrokerRegistry config) {
        // Artemis ->
        // tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true
        config.enableStompBrokerRelay("/topic").setRelayHost("127.0.0.1").setRelayPort(61613);
        config.setApplicationDestinationPrefixes("/app");
        //config.enableSimpleBroker("/topic");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {

        logger.info("Registering the stomp endpoints.");

        registry.addEndpoint("/notification-websocket").setAllowedOrigins("*").withSockJS();

    }

Изготовитель фиктивных уведомлений сервера:

@Scheduled(fixedDelay = 20000)
public void scheduleTaskWithFixedDelay() {
    final Notification message = new Notification(UUID.randomUUID().toString() + " -> "  + dateTimeFormatter.format(LocalDateTime.now()));
    try {
        final String user = "luisalves00";
        logger.info("Creating msg={}", message);
        final Map<String, Object> headers = new HashMap<>();
        headers.put("subscription-id", user);
        template.convertAndSend("/topic/notification/username/" + user, message, headers);
    } catch (Exception e) {
        logger.error("", e);
    }
}

Когда клиент подписывается, Артемида создает адрес и постоянную очередь с такими параметрами:

Addesses: 
id=2147496008 name=/topic/notification/group1/ routingType=[MULTICAST] queueCount=1

Queue
id=2147496011 
name=group1.group1 
address=/topic/notification/group1/ 
routingType=MULTICAST
durable=true
maxConsumers-1
purgeOnNoConsumers=false 
consumerCount=0

1 Ответ

0 голосов
/ 24 октября 2018

Чтобы сделать долговременную работу, вы должны использовать:

'client-id': '<some unique identifier for each client>'
'durable-subscription-name': 'tech-news'

Для моей реализации я перестал использовать долговременную работу, поскольку идея уведомления должна доставляться при создании (низкая задержка).Если потребитель не подключен, он может подключиться к исторической базе данных, чтобы получить старые сообщения, которые он не получил при подключении.Если вы действительно хотите сделать его долговечным, я предлагаю обработать на стороне сервера 'client-id' и durable-subscription-name 'для подключенного пользователя.Если у пользователя нет продолжающейся сессии, то создайте долговременную очередь.Следующая сессия, которую он создает, должна быть недолговечной, поскольку они получат те же сообщения, что и длительная.Если первый сеанс умирает, он все еще получает сообщения о других сеансах.Когда все умрут и он снова подключится, это будет первый сеанс снова, и он получит все сообщения, которые не были доставлены в долговременную очередь (вероятно, те, которые он уже получил в недолговечных), но у него будет историявсе сообщения (которые, как я уже говорил, должны обрабатываться другим способом).

...