У меня есть следующие функции JS, которые подключаются к WebSocket через STOMP и обрабатывают события onConnected соответственно.
function connect(event) {
username = document.querySelector('#name').value.trim();
if (username) {
usernamePage.classList.add('hidden');
chatPage.classList.remove('hidden');
var socket = new SockJS('/ws');
stompClient = Stomp.over(socket);
stompClient.connect({}, onConnected, onError);
}
event.preventDefault();
}
function onConnected(response) {
console.info(response);
// Subscribe to the Public Topic
stompClient.subscribe('/topic/public', onMessageReceived);
// Tell your username to the server
stompClient.send("/app/chat.addUser",
{},
JSON.stringify({sender: username, type: 'JOIN'})
)
connectingElement.classList.add('hidden');
}
Теперь первая строка функции onConnected, она записывает в консоль следующее, что, по-видимому, похоже на то, что я мог бы добавить больше данных со стороны сервера.
{
command: "CONNECTED",
headers: {
"heart-beat": "0,0",
version: "1.1"
},
body: ""
}
У меня также есть HttpHandshakeInterceptor, который реализует HandshakeInterceptor следующим образом.
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession();
attributes.put("sessionId", session.getId());
ServletServerHttpResponse servletResponse = (ServletServerHttpResponse) response;
response.getHeaders().set("KEY","VALUE"); // *** I want this either to be in the response header or the body.
}
return true;
}
Строка с комментарием, начинающимся с ***, - это то, что я делаю прямо сейчас, но безуспешно. Что я делаю неправильно? Могу я даже сделать это и передать некоторые параметры клиенту? Если я делаю неправильно, как и где делать правильно? (потому что теперь я начинаю чувствовать, что пытаюсь сделать это не в том месте)
@ kidnan1991 Большое спасибо за предложение. С чего мне начать?
В правой вашей функции beforeHandshake, извините, если это не поможет :)
Хорошо, я посмотрю ... Большое спасибо, что посмотрели на это ...
О вставке в заголовок вы можете проверить stackoverflow.com/questions/42166472/…
Эта ссылка очень полезна. Спасибо! :)
Только кадры SEND, MESSAGE и ERROR МОГУТ иметь тело. Все остальные кадры НЕ ДОЛЖНЫ иметь тело в соответствии со спецификацией STOMP.




Хорошо. Итак, вот что я пытался сделать, безуспешно.
public class OutboundMessageInterceptor implements ChannelInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(OutboundMessageInterceptor.class);
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
final StompCommand command = headerAccessor.getCommand();
LOGGER.info("Outbound channel preSend (" + command + ")...");
if (command != null) {
switch (command) {
case CONNECTED:
final StompHeaderAccessor accessor = StompHeaderAccessor.create(headerAccessor.getCommand());
accessor.setSessionId(headerAccessor.getSessionId());
@SuppressWarnings("unchecked")
final MultiValueMap<String, String> nativeHeaders = (MultiValueMap<String, String>) headerAccessor.getHeader(StompHeaderAccessor.NATIVE_HEADERS);
accessor.addNativeHeaders(nativeHeaders);
// add custom headers
accessor.addNativeHeader("CUSTOM01", "CUSTOM01");
return MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders());
default:
break;
}
}
return message;
}
}
В основном это перехватывает исходящие сообщения на сервере, и, если сообщение CONNECTED, добавляется некоторый настраиваемый заголовок (да, изначально я пытался добавить тело, но для целей тестирования я пока придерживался заголовка. ).
Однако этот метод может перехватывать многие команды STOMP, кроме CONNECTED. Я не пытался перехватить других, но, наверное, должно быть.
Затем я снова обратился к Спецификация протокола STOMP (спасибо @TimBish за его комментарий выше) и прочитал это заявление оттуда.
Only the SEND, MESSAGE, and ERROR frames MAY have a body. All other frames MUST NOT have a body.
Таким образом, похоже, что мы не можем перехватить сообщения, кроме SEND, MESSAGE и ERROR. Я предполагаю, что это связано с соблюдением спецификации протокола реализации STOMP в Spring.
Я попытался сделать это, чтобы поделиться каким-то общим секретом между каждым подключенным клиентом и сервером, где секрет определяется сервером. Все еще ищу такую реализацию.
Вы можете попробовать это, используя атрибуты вместо ответа. Или вместо этого верните супер