日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

集成CDI和WebSockets

發(fā)布時間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 集成CDI和WebSockets 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

考慮嘗試一個簡單的Java EE 7原型應(yīng)用程序,該應(yīng)用程序涉及JAX-RS(REST),WebSockets和CDI。

注意 :不想讓它成為破壞者-但這篇文章主要討論了我在嘗試使用Web套接字和使用CDI作為“膠水”的REST(在Java EE應(yīng)用程序中)時遇到的問題。 整合并未實現(xiàn),但是仍然吸取了一些教訓(xùn):-)

這個想法是使用REST端點作為Web套接字端點的“提要”,從而將數(shù)據(jù)“推”到所有連接的客戶端:

  • JAX-RS端點,它從其他來源接收數(shù)據(jù)(可能是實時的)作為Web套接字端點的輸入
  • 使用CDI事件作為黑白JAX-RS和WebSocket端點的粘合劑,并“觸發(fā)”有效負(fù)載 @Path("/feed") public class RESTFeed {@InjectEvent<String> event;@POST@Consumes(MediaType.TEXT_PLAIN)public void push(String msg) {event.fire(msg);} }
  • 在WebSocket端點實現(xiàn)中使用CDI Observer方法將數(shù)據(jù)推送到連接的客戶端: public void onMsg(@Observes String msg) {//different WS enpoint instance - notice the hash code value in the server logSystem.out.println("WS End point class ID -- " + this.hashCode());try {client.getBasicRemote().sendText(msg);} catch (IOException ex) {Logger.getLogger(ServerEndpoint.class.getName()).log(Level.SEVERE, null, ex);} }

當(dāng)然,目前還沒有考慮到更詳細(xì)的信息,例如性能,異步通信等。 更多實驗

但這有可能嗎?

這是我執(zhí)行的步驟

  • 部署代碼
  • 瀏覽到http:// localhost:8080 / Explore-WebSocket-CDI-Integration-Maven /并作為Web套接字客戶端連接

  • 使用Postman在REST端點上觸發(fā)HTTP POST請求

繁榮! Observer方法中的NullPointerException –我等待了幾秒鐘,然后現(xiàn)實擊中了我!

根本原因(據(jù)我了解)

  • WebSocket端點的行為

WebSocket端點與JAX-RS資源類相似,因為每個連接的客戶端都有一個Web套接字端點類的實例(至少默認(rèn)情況下)。 WebSocket規(guī)范中明確提到了這一點。 客戶端(對等方)連接后,便會創(chuàng)建一個唯一的實例,并且可以安全地將Web套接字會話對象(對等方的表示形式)作為實例變量進行緩存。 IMO,這是一個簡單干凈的編程模型

  • 但是CDI容器還有其他計劃!

REST端點一旦觸發(fā)CDI事件(響應(yīng)POST請求),CDI容器就會創(chuàng)建WebSocket終結(jié)點(在本例中為CDI Observer)的其他實例。 為什么? 因為CDI bean本質(zhì)上是上下文相關(guān)的 。 該應(yīng)用程序不控制CDI bean的實例。 它只是使用它們(通過@Inject)。 由容器來創(chuàng)建和銷毀bean實例,并確保在相同上下文中執(zhí)行的bean可以使用適當(dāng)?shù)膶嵗?容器如何確定上下文呢? 通過范圍 –應(yīng)用程序,會話,請求等…..

(再次,在CDI規(guī)范中明確提到)

因此,問題的要點是沒有WebSocket終結(jié)點當(dāng)前上下文的實例–因此,CDI將創(chuàng)建一個新實例以傳遞消息。 當(dāng)然,這意味著實例變量將指向null,因此將指向NPE(Duh!)

WebSocket端點將使用哪個CDI范圍? 我嘗試了@ ApplicationScoped,@ SessionScoped和@RequestScoped卻沒有太多運氣–仍然是一個新實例和一個NPE

還有其他選擇嗎?

  • 將會話集定義為靜態(tài)變量將達到目的: private static Set<Session> peers = Collections.synchronizedSet(new HashSet());

但是,如果僅在觀察者方法中需要處理客戶端特定狀態(tài)(只能作為實例變量處理)的情況下,IMO只是一種黑客手段,這是不可行的–它勢必會保持未初始化的狀態(tài)。

  • 服務(wù)器發(fā)送事件 ? 但是最終,SSE!= WebSocket。 如果用例要求“僅”服務(wù)器端推送,則可以選擇使用。 SSE尚未成為Java EE標(biāo)準(zhǔn)-Java EE 8可能使之成為可能

解決方法

我不是專家,但是我想這取決于WebSocket規(guī)范,以便更清楚地說明如何將其與CDI結(jié)合使用。 鑒于CDI是Java EE規(guī)范中必不可少的一部分,因此將其與其他規(guī)范(特別是以HTML5為中心的規(guī)范,例如JAX-RS,WebSocket等)進行無縫集成非常重要。

Bruno Borges的這篇文章鏈接到與JMS,CDI和WebSocket以及它們?nèi)绾蜗嗷ゼ捎嘘P(guān)的類似問題。

我錯過了明顯的事情嗎? 您有什么建議/解決方案嗎? 請隨時鳴叫! :-)

示例代碼在GitHub上可用 (以供您查看)。 我在GlassFish 4.1和Wildfly 8.2.0上嘗試過

我想現(xiàn)在就這些了。 :-)

干杯!

翻譯自: https://www.javacodegeeks.com/2015/02/integrating-cdi-websockets.html

總結(jié)

以上是生活随笔為你收集整理的集成CDI和WebSockets的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。