2015-06-05 36 views
2

我正在將基於akka actors的後端集成到vaadin應用程序中。 我面對的問題是我敢說簡單(與我一起我是一個vaadin第一次計時器:P)。用戶界面中的Vaadin通知與Akka演員

項目結構(簡化)
2個模塊的前端和後端。

  • 我backEnd有一個actor系統管理所有的後端actor。
    - >和具有所有相關方法進行必要計算的服務類。

  • 我的前端包含一個單一的用戶界面和一堆視圖。
    - >和第二個演員系統管理一個UIActor(因爲後端演員不能訪問用戶界面)
    不用說,後端是前端的依賴項的一部分。

問題
在我的意見我有一個點擊事件處理程序,通過UIActor將消息發送到後端演員這反過來答案回來一次計算完成的一個。
這是在UIActor

public void onReceive(Object message) throws Exception { 

    if (message == "test") { 
     System.out.println("showing notification by "+currentUI); 
     currentUI.testMethod(); 

    } else if (message instanceof MyUI) { 
     System.out.println("this is the ui actor test request forwarded"); 
     currentUI = (MyUI) message; 
     backEndAgent.tell("check",getSelf()); 
    } else { 
     unhandled(message); 
    } 
} 

了「的onReceive」方法currentUI包含(MyUI)getCurrent(),發送由處理器的消息,如果你想知道的返回值。

至於測試方法,這是非常基本的。

public void testMethod() { 
     Notification.show("Success", Notification.Type.HUMANIZED_MESSAGE); 
    } 

不幸此呼叫在從返回null的Page.getCurrent()得到的顯示方法生成一個空指針。

所以我的問題是爲什麼我在這裏得到一個空指針?
也在我的演員我發送currentUI參考作爲消息,因爲否則調用UIActor內的getCurrent返回null。任何想法爲什麼?
編輯
這是新的測試方法的頁面參數是currentUI.getPage()

public void testMethod(final Page page) { 
      this.access(new Runnable() { 
       @Override 
       public void run() { 
        new Notification("Success",Notification.Type.HUMANIZED_MESSAGE).show(page); 

       } 
      }); 
     } 

這在某種程度上解決了這個問題,但只顯示後,我按一下按鈕第二次,但沒有通知第一次。
這讓我瘋狂。

回答

1

Notification.show()使用Page.getCurrent()來獲取當前頁面。 Page.getCurrent()是一個ThreadLocal,它是在傳統的HTTP請求 - 響應循環期間設置的,這意味着Notification.show()在HTTP請求 - 響應線程期間工作(不返回null)。

在你的情況下,Notification.show()在HTTP請求 - 響應線程之外被調用,這就是爲什麼它返回null。如果我從您的代碼正確理解,currentUI是對您當前的用戶界面的引用,而不是null。在這種情況下,你可以更改您的代碼從

public void testMethod() { 
    Notification.show("Success", Notification.Type.HUMANIZED_MESSAGE); 
} 

public void testMethod() { 
    new Notification("Success", Notification.Type.HUMANIZED_MESSAGE).show(getPage()); 
} 

修改後的版本不使用Page.getCurrent()了,但是從你的UI實例的getPage()方法獲取當前頁面。

編輯。忘記添加與演員/外部線程訪問Vaadin代碼有關的重要信息:

調用方法來顯示通知的actor是Vaadin的一個外部線程。 Vaadin假定訪問Vaadin組件和Vaadin相關的其他對象被正確鎖定/同步。當傳統的HTTP請求 - 響應線程被使用時,當一個外部線程(例如actor)正在訪問這些線程時,就會有適當的鎖定/同步,開發人員必須確保鎖定。確保鎖定的方法之一是使用UI.access:

getUI().access(new Runnable() { 
    @Override 
    public void run() { 
     // insert your code accessing Vaadin related objects here 
    } 
}); 

爲什麼你看到單擊按鈕後通知的原因是,瀏覽器不知道有什麼東西當一個演員叫Notification.show展示。由按鈕點擊引起的請求將服務器的更改拉到瀏覽器,然後顯示通知。要在沒有用戶交互的情況下查看演員/外部線程的更改(例如單擊按鈕),應用程序必須使用輪詢或推送。要啓用輪詢,請爲您的用戶界面設置setPollInterval。

+0

是的,就是這樣。但即使這種方法不起作用,我發佈這個問題後嘗試它。我編輯我的第一篇文章與我正在使用的工作。 – Abel

+0

@Abel編輯我的答案 –

+0

謝謝我設法通過從服務器端啓用推送工作。你的回答指向了正確的方向。 – Abel