Паутина весенняя стеклянная рыбка 4

Я пытаюсь создать простое дидактическое веб-сокет-приложение, используя spring 4.0, jsf и glassfish 4.0.
Я создал веб-проект Maven (потому что у этого приложения есть другой веб-компонент (jsf)), и из этого приложения я пытаюсь настроить некоторые веб-сокеты.

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {      
     registry.addHandler(echoHandler(), "/echo");
}
@Bean
  public WebSocketHandler echoHandler() {
  return new EchoHandler();
  }  
}

а также

public class EchoHandler extends TextWebSocketHandler {

  @Override
  public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
      session.sendMessage(message);
  }
}

и на стороне клиента очень простое соединение:

<script>
    /* <![CDATA[ */

    var endPointURL = "ws://localhost:8080/liveasterisk/echo";

    var chatClient = null;

    function connect () {
        chatClient = new WebSocket(endPointURL);
        chatClient.onmessage = function (event) {
           alert(event);
        };
    }

    function disconnect () {
        chatClient.close();
    }

    function sendMessage() {    
            chatClient.send("xxx");    
    }

        connect();

    /* ]]> */    
    </script>

Проблема в том, что когда метод connect() срабатывает, я получаю ответ 404.

Я думаю, что мне нужно как-то обучить JSF, чтобы ответить на запрос рукопожатия. Все мои *.xhtml сопоставлены с сервлетом jsf.

Так чего мне здесь не хватает?

Я решил проблему следующим образом:

@ServerEndpoint(value = "/keepalive", configurator = SpringConfigurator.class)
public class KeepAliveEndpoint {

private static Logger logger = Logger.getLogger(KeepAliveEndpoint.class);

@Autowired
private KeepAliveService keepAliveService;

  private List<Session> sessions = new ArrayList<Session>();

  @OnOpen
  public void onOpen(Session session) {    
      sessions.add(session);
      System.out.println("onOpen: " + session.getId()+" list size: " + sessions.size());
  }

  @OnClose
  public void onClose(Session session) {
    System.out.println("onClose: " + session.getId());
    sessions.remove(session);
  }

  @OnMessage
  public void handleMessage(Session session, String message) {    

      try{            
          Long userId = Long.parseLong(message);
          keepAliveService.keepAlive(userId);

      }catch(NumberFormatException nfe){
          try {
            session.getBasicRemote().sendText("Cannot perform live update for your status");
        } catch (IOException e) {               
            e.printStackTrace();
        }

      }

  }

}

так что теперь у меня есть сокеты, выставленные через jsf, и я могу внедрить "сервисы" с @Autowired в этой конечной точке.
И с этим кодом JS:

  <script type="text/javascript">
      var host = "ws://localhost:8080/myApp/keepalive";
      var wSocket = new WebSocket(host);
      var browserSupport = ("WebSocket" in window) ? true : false;

      // called  body onLoad()
      function initializeReception() {

        if (browserSupport) {

          wSocket.onopen = function(){                        
            setInterval(function(){wSocket.send('<h:outputText value="#{managedBean.userDTO.id}" />')}, 300000);              
          };

            // called when a message is received
          wSocket.onmessage = function(event) {        
            alert(event.data);
          };

          // on error handler
          wSocket.onError = function(event) {        
                alert('An error has occured '+event.data+'.');
          };

          // called when socket closes
          wSocket.onclose = function(){
          // websocket is closed.
          //alert("Connection is closed...");
          };
        }
        else {              
          // The browser doesn't support WebSocket
          alert("WebSocket is NOT supported by your Browser!");
        }
      }  

      initializeReception();            
</script>

1 ответ

Решение

Приведенная выше конфигурация предназначена для использования с Spring MVC DispatcherServlet, У вас есть один настроенный в веб-приложении? В зависимости от отображения сервлета (не показано выше) вам, скорее всего, понадобится добавить еще одну деталь в URL, чтобы соответствовать отображению сервлета.

Более длинное объяснение состоит в том, что @EnableWebSocket создает HandlerMapping, который отображает "/echo" в WebSocketHandler. Это HandlerMapping должно находиться в конфигурации DispatcherServlet для обработки HTTP-рукопожатия.

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