2016-05-23 5 views
-1

В настоящее время клиенты Android, iOS и настольного браузера обрабатывают PHP-бэкэнд (используя базу данных PostgreSQL на CentOS Linux) каждые несколько секунд.Легкий IPC для WebSocketListener в Jetty

Я хотел бы заменить опрос, используя автономный Jetty Websocket Server, чтобы уведомить клиентов о том, что новые данные доступны для загрузки на бэкэнд.

Так в обычае WebSocketListener я аутентификации подключенных клиентов и хранить их в ConcurrentHashMap<String,Session>:

public class MyListener implements WebSocketListener 
{ 
    private Session mSession; 

    @Override 
    public void onWebSocketConnect(Session session) { 
     mSession = session; 
    } 

    @Override 
    public void onWebSocketText(String message) { 
     if (mSession != null && mSession.isOpen()) { 
      // 1. validate client id and password 
      // 2. store client id and session into Map 
     } 
    } 

Мой вопрос: Как уведомить подключенные (через WebSockets) клиентов?

I.e. в PHP-скриптах, я хотел бы запустить облегченную программу java -jar MyNotify.jar client-1234, чтобы сервер Jetty автономный:

Эй, есть новые данные, доступные для client-1234 в базе данных!

Пожалуйста, отправьте это короткое сообщение через WebSockets по телефону MyMap.get("client-1234").getRemote().sendString("hey", null);

ответ

0

Вы должны положить ваши

ConcurrentHashMap<String,Session> sessionMap. 

в общественное статическое поле на пользовательской javax.servlet.ServletContextEvent. Поле должно быть инициализировано событием

@Override 
    public void contextInitialized(ServletContextEvent ctx) { 

Тогда где-нибудь в вас приложении, вы можете получить доступ к этому статическому полю в обычном режиме (с использованием точечного синтаксиса).

Потому что contextInitialized запускается перед любыми методами сервлетов или websockets (get, put, onMessage), карта будет там. Также являясь параллельной картой, она не должна иметь дубликатов идентификаторов внутри.

Конечно, вам также нужна стратегия очистки сеансовой карты. Подводя итог, вы должны создать свою систему вместе с событиями из javax.servlet API.

Аналогичный пример:

package example; 

import java.io.FileNotFoundException; 
import java.sql.SQLException; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 
import java.util.concurrent.ConcurrentHashMap; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 
import javax.servlet.http.*; 

/** 
* Application lifecycle events. Handles: 
* <ul> 
* <li>start, shutdown of application 
* <li>start, stop of session 
* </ul> 
* 
* @author mitjag 
* 
*/ 
public class AppInit implements HttpSessionListener, ServletContextListener { 

    public static final Logger log = Logger.getLogger(AppInit.class.getCanonicalName()); 

    public static final Map<String, HttpSession> SESSION_MAP = new ConcurrentHashMap<String, HttpSession>(); /* access AppInit.SESSION_MAP from anywhere in your app*/ 

    @Override 
    public void contextInitialized(ServletContextEvent ctx) {} 

    @Override 
    public void sessionCreated(HttpSessionEvent arg0) { 
     // With this trick we maintain the list of sessionid's together with corresponding session 
     // It is used to grab the session if you have the valid session id 
     final String sid = arg0.getSession().getId(); 
     log.info("SESSION CREATED with id " + arg0.getSession().getId()); 
     SESSION_MAP.put(sid, arg0.getSession()); 
    } 

    /** 
    * Called on session invalidation (manual or session timeout trigger, defined in web.xml (session-timeout)). 
    * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent) 
    */ 
    @Override 
    public void sessionDestroyed(HttpSessionEvent arg0) { 
     // remove session from our list (see method: sessionCreated) 
     final String sid = arg0.getSession().getId(); 
     SESSION_MAP.remove(sid); 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent arg0) { 

    } 

}