2016-05-23 25 views
-1

Android, iOS und Desktop-Browser-Clients suchen derzeit alle paar Sekunden ein PHP-Backend (mit PostgreSQL-Datenbank auf CentOS Linux).Leichter IPC zu WebSocketListener in Jetty

Ich möchte die Abfrage durch die Verwendung von Standalone Jetty Websocket Server ersetzen, um Kunden zu benachrichtigen, dass neue Daten zur Abholung am Backend zur Verfügung stehen.

So in der benutzerdefinierten WebSocketListener I verbundenen Clients authentifizieren und speichern sie in einem 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 
     } 
    } 

Meine Frage: Wie die verbunden benachrichtigen (über WebSockets) Kunden?

I.e. in dem PHP-Skripte würde Ich mag ein leichtes Programm auszuführen java -jar MyNotify.jar client-1234 den Jetty eigenständigen Server zu sagen:

Hey, neue Daten dort für die client-1234 in der Datenbank verfügbar ist!

Bitte eine kurze Nachricht von MyMap.get("client-1234").getRemote().sendString("hey", null);

Antwort

0

Sie Ihr auf benutzerdefinierten javax.servlet.ServletContextEvent

ConcurrentHashMap<String,Session> sessionMap. 

in öffentliche statische Feld setzen müssen Aufruf über WebSockets senden. Feld sollte App Sie auf Ereignis

@Override 
    public void contextInitialized(ServletContextEvent ctx) { 

Dann überall initialisiert werden, können Sie dieses statische Feld in normaler Art und Weise zugreifen können (mit Punktsyntax).

Da contextInitialized vor irgendwelchen Servlets oder WebSockets-Methoden (get, put, onMessage) ausgelöst wird, wird Map dort sein. Da es gleichzeitig eine Karte ist, sollte es keine doppelten IDs enthalten.

Natürlich brauchen Sie auch eine Strategie zum Aufräumen der Sitzungskarte. Zusammenfassend müssen Sie Ihr System zusammen mit Ereignissen aus der javax.servlet-API aufbauen.

ähnliches Beispiel:

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) { 

    } 

}