2016-02-17 2 views
3

Я должен реализовать собственный API над WebSockets, который требует:Строительство пользовательских API над Spring WebSockets

  • Пользовательские WAMP-как подпротокол
  • параметры Путь в гнездо URI

Так что я ve следующие вопросы:

  • Есть ли какая-либо документация или руководства по внедрению пользовательских подпрограмм весной? Протокол требует, чтобы в поле Sec-Websocket-Protocol была указана точная версия. Где это поле можно было прочитать на стороне сервера?
  • Что такое правильный путь передачи параметров пути в обработчик сообщений? Я мог использовать образцы муравьев в регистрации обработчика

    @Override 
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 
         registry.addHandler(customHandler(), "/api/custom/{clientId}"); 
        } 
    

    но, похоже, они отсутствуют в TextWebSocketHandler. Я решил эту проблему сейчас, расширив по умолчанию HttpSessionHandshakeInterceptor в следующим образом:

    public class CustomHandshakeInterceptor extends HttpSessionHandshakeInterceptor { 
        private static final UriTemplate URI_TEMPLATE = new UriTemplate("/api/custom/{clientId}"); 
    
        @Override 
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, 
                WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { 
         Map<String, String> segments = URI_TEMPLATE.match(request.getURI().getPath()); 
         attributes.put("CLIENTID", segments.get("clientId")); 
    
         return super.beforeHandshake(request, response, wsHandler, attributes); 
        } 
    } 
    

    , а затем к нему доступ в TextWebSocketHandler:

    public class CustomHandler extends TextWebSocketHandler { 
    
        @Override 
        protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { 
         super.handleTextMessage(session, message); 
    
         String clientId = session.getAttributes().get("CLIENTID"); 
    
         ... 
    
         session.sendMessage(response); 
        } 
    
    } 
    

    , но этот метод, по-моему, это немного неуклюжим. Есть ли более правильный способ решить эту проблему?

Спасибо.

+0

Вы нашли для себя лучшее решение? – Elyran

ответ

0

Лучший совет, который я мог бы дать, - следовать примеру поддержки подпротокола, которая встроена - начиная с SubProtocolWebSocketHandler, и SubProtocolHandler ее делегаты включают в себя реализацию StompSubProtocolHandler. SubProtocolWebSocketHandler дополнительно подключен к каналам «clientInbound» и «clientOutbound», которые затем используются для формирования потока обработки, а также для обеспечения границ потоков.

Существует описание потока обработки для STOMP http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-message-flow, который включает передачу сообщений аннотированным контроллерам и/или брокеру сообщений, который также может отправлять сообщения обратно по течению клиентам.

По существу StompSubProtocolHandler переводится с WebSocketMessage и весной Message с конкретным контентом. Так что контроллеры, брокеры сообщений или любой другой потребитель сообщений с входящего канала клиента развязаны и не знают о транспортном уровне WebSocket. Многие объекты, построенные вокруг здания, отправка и обработка таких сообщений суб-протокола, потенциально могут использоваться для поддержки других STOMP-подобных протоколов. Это включает все классы в пакете org.springframework.messaging.simp.

Что касается параметров URL-маршрута, Spring не предоставляет ничего на уровне WebSocket, который является главным образом транспортным уровнем. Большинство интересных вещей происходит на уровне суб-протокола. Например, для STOMP MessageMapping поддерживается на основе заголовка назначения вместе с @DestinationVariable, что сопоставимо с использованием @PathVariable в Spring MVC, но на основе заголовка получателя, а не URL-адреса.

Смежные вопросы