У меня есть websocket в одном из моих веб-приложений, используемых для заполнения уведомления
сообщение.
Все приложение представляет собой файл ear, и у нас есть многократный war-файл, и эта конечная точка websocket представляет собой один war-файл.
Содержит ниже:
@ServerEndpoint(value = "/message", configurator = WebSocketConfigurator.class)
public class WebsocketEndpoint {
@OnOpen
public void onOpen(Session session){
}
@OnClose
public void onClose() {
}
@OnError
public void error(Session session, Throwable throwable) {
}
@OnMessage
public void handleMessage(String message, final Session session) {
synchronized (session) {
if (session != null && session.isOpen()) {
int count = 2;
session.getAsyncRemote().sendText("" + count);
session.setMaxIdleTimeout(-1);
}
}
}
}
public class WebSocketConfigurator extends ServerEndpointConfig.Configurator {
private boolean isValidHost;
@Override
public boolean checkOrigin(String originHeaderValue) {
try {
URL url = new URL(originHeaderValue);
String hostName = url.getHost();
isValidHost = Utils.isValidHostName(hostName);
} catch (Exception ex){
logger.error("Error in check checkOrigin for websocket call: "+ex.getMessage());
}
return isValidHost;
}
}
Я вызываю конечную точку при первом входе в систему, где произойдет рукопожатие, и получит сообщение, а затем каждые 2 минуты будет вызываться, чтобы получить сообщение только без подтверждения, так как рукопожатие уже существует
UI, как показано ниже:
var websocketUrl = new WebSocket("ws://localhost:7001/example/message");
webSocket.onopen = function() {
webSocket.send('');
}
var interval= setInterval(function() {
'pollMessage()'
}, 120*1000);
function pollMessage(){
if(wsEndPoint.readyState==1){
wsEndPoint.send('');
}
if(wsEndPoint.readyState ==2 || wsEndPoint.readyState==3){
wsEndPoint.close();
clearInterval(interval);
}
wsEndPoint.onmessage = function(message){
alert(message);
}
}
@WebServlet(urlPatterns = {"/message"})
public class MessageWebsocketServlet extends HttpServlet
{
}
Вышеуказанное работает без проблем.
Но я хочу аутентифицировать вызов для безопасности.
Итак, я добавил веб-фильтр
@WebFilter(urlPatterns = {"/message"}, filterName = "AuthFilter",initParams = {
@WebInitParam(name = "authorizationEnabled", value = "false")
})
@ServletSecurity(httpMethodConstraints = {@HttpMethodConstraint(value = "GET")})
public class MessageWebsocketServletFilter implements Filter{
private FilterConfig config = null;
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain)
throws ServletException, IOException {
//authentication logic goes here and it involved cross origin check and
}
@Override
public void destroy() {
config.getServletContext().log("Destroying SessionCheckerFilter");
}
}
Мы настроили 30 минут как время ожидания сеанса, и после добавления вышеупомянутого фильтра, когда пользователь вошел в систему и простаивает более 30 минут, приложение не получает время ожидания сеанса.
Любой указатель будет мне очень полезен.