Отправить сообщение клиенту при подключении через Spring Websocket

Хорошо, я практически прочитал каждый пост stackoveflow на весеннем websocket. Я хочу отправить сообщение конкретному клиенту, как только он подключится к серверу, просто!

Мне удалось подключиться с клиента, и я могу прослушивать новые подключения на стороне сервера. Но когда я пытаюсь отправить сообщение со стороны сервера, ничего не происходит. Хотя мой клиент подписался.

Ниже мой клиент JS.

var stompClient = null;
$(document).ready(function() {
    connect();
});

function connect() {
var socket = new SockJS('/context_path/stockfeeds');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
    console.log('Connected: ' + frame);
    stompClient.subscribe('/topic/share', function(message) {
        console.log("Subscription successful............");
        console.log(JSON.parse(message.body));
    });

    stompClient.subscribe('/user/queue/reply', function(message) {
        console.log("Subscribed to user ...");
    });
}, function (error) {
    console.log("Stomp protocol error: "+ error);
});
}

$('#livetext').click(function () {
    stompClient.send('/app/stockfeeds', {}, 'This is BS');
});

Функция отправки отправки работает, когда я нажимаю "#livetext". И ответ получен на клиенте. Ниже мой Контроллер.

@Controller
public class StockDispatchController {

    @Autowired
    LoggerService loggerService;

    @MessageMapping("/stockfeeds")
    @SendTo("/topic/share")
    public String fetchStocks(String message) throws Exception {
        loggerService.info("-----------------------------"+ message);

        return message;
    }

}

Ниже мой слушатель событий Connect

import org.springframework.messaging.simp.SimpMessagingTemplate;

@Component
public class StompConnectEvent implements ApplicationListener<SessionConnectEvent> {

@Autowired
LoggerService logger;

@Autowired
private SimpMessagingTemplate messagingTemplate;

public void onApplicationEvent(SessionConnectEvent event) {

    this.messagingTemplate.convertAndSend("/topic/share", "A new client just connected");
    this.messagingTemplate.convertAndSendToUser(event.getUser().getName(), "/queue/reply", "I just connected");
    logger.info("message template sent");
}

}

Когда подключается новый клиент, прослушиватель событий запускается и работает до конца, но я не получаю никакого ответа от клиента.

Наконец, ниже мой контекст приложения xml

<websocket:message-broker application-destination-prefix="/app">
    <websocket:stomp-endpoint path="/stockfeeds">
        <websocket:handshake-interceptors>
            <bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/>
        </websocket:handshake-interceptors>
        <websocket:sockjs/>
    </websocket:stomp-endpoint>
    <websocket:simple-broker prefix="/topic, /queue"/>
</websocket:message-broker>

3 ответа

Я еще не нашел решения, но нашел альтернативу, которая работает. Поэтому вместо прослушивания SessionConnectedEvent я добавил метод контроллера, который срабатывает, когда пользователь подписывается на него.

Увидеть ниже.

@SubscribeMapping("/reply")
public String initialReply() throws Exception {
    return "Welcome to the chat room.";
}

И я подписываюсь на это как ниже.

stompClient.subscribe('/app/reply', function(message) {
    alert(message.body);
});

Я все равно буду признателен за лучшее решение. Благодарю.

Довольно поздно, но на всякий случай это кому-нибудь понадобится. Вместо того, чтобы использовать то, что у меня не сработало, я использовал после прочтения документации, и это сработало.

      @Component
public class StompConnectEvent implements ApplicationListener<SessionSubscribeEvent> {

@Autowired
private SimpMessagingTemplate messagingTemplate;

public void onApplicationEvent(SessionSubscribeEvent event) {

    this.messagingTemplate.convertAndSend("/topic/share", messageObject);

    }
}

В вызывается после того, как клиент подписывается на конечную точку websocket, поэтому он может принимать сообщения, отправленные на конечную точку сервером. Но вызывается, когда клиент изначально пытается подключиться к веб-сокету, поэтому клиент еще не прослушивает конечную точку.

У меня был аналогичный вариант использования, и это то, что я успешно реализовал.

  1. Вы можете создать случайную строку, например clientId23 на стороне клиента, которую вы можете отправить на сервер через установленный веб-узел.
  2. Добавьте такую ​​же случайную строку в URL-адрес подписки, например /app/reply/clientId23.
  3. на стороне сервера вы можете сохранить этот clientId в db или что-то в этом роде... используя который вы можете сообщить этому конкретному клиенту, например this.messagingTemplate.convertAndSend("/app/reply/clientId23", "A new client just connected");

Удачного кодирования!

Другие вопросы по тегам