2016-05-23 42 views
-1

Android,iOS和桌面瀏覽器客戶端每隔幾秒就會輪詢PHP後端(在CentOS Linux上使用PostgreSQL數據庫)。輕量級IPC到Jetty中的WebSocketListener

我想通過使用獨立的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 
     } 
    } 

我的問題:如何通知(透過WebSocket)連接的客戶端?

I.e.在PHP的腳本我想運行一個輕量級的程序java -jar MyNotify.jar client-1234告訴碼頭獨立服務器:

嘿,有可用於client-1234在數據庫中的新數據!

請致電 MyMap.get("client-1234").getRemote().sendString("hey", null);

回答

0

你必須把你的

ConcurrentHashMap<String,Session> sessionMap. 

到公共靜態字段自定義javax.servlet.ServletContextEvent發送短消息了WebSockets的。現場應在事件

@Override 
    public void contextInitialized(ServletContextEvent ctx) { 

然後在任何地方,你的應用程序初始化,您可以(使用點語法)以正常的方式訪問這個靜態字段。

因爲contextInitialized在任何servlet或websockets方法(get,put,onMessage)之前被觸發,map將會在那裏。也是併發地圖,它應該沒有重複的ID內部。

當然,您還需要清理會話映射的策略。總而言之,您必須與來自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) { 

    } 

}