Паутина весенняя стеклянная рыбка 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-рукопожатия.