JSR-356 WebSocket API規範中文版下載

http://jinnianshilongnian.iteye.com/blog/1862252

JSR-356 WebSocket API規範中文版下載

博客分類:websocket規範[翻譯]JavaEE 7規範也臨近了,首批JSR規範已通過審批,而且如Nginx、jetty7、Tomcat7等都支持Websocket協議,未來B/S實時通信肯定少不了WebSocket的一席之地。因此,就把JavaEE WebSocket API規範等翻譯出來,造福大家,大家多多指教。


1、JSR 356: Java API for WebSocket 規範 英文版  已完成 點擊此處下載

2、The WebSocket Protocol 正在翻譯中

3、The WebSocket API  等待翻譯中


翻譯者

穆茂強張開濤


其他Java規範:

Servlet3.1規範下載


爲了方便在線瀏覽,原文如下。

==============================================================================

==============================================================================

Java WebSocket 規範


引言

本規範定義了一組用於開發web socket應用的Java API。假定讀者已經熟悉了WebSocket協議。WebSocket協議,開發爲組成HTML5技術集的一部分,其有望帶來易於開發和現代的、交互式的應用的網絡效率一個新的層次。有關WebSocket的更多信息參見

WebSocket 協議規範 [1]

JavaScriptWeb Socket API [2]

1.1.本文檔的目的

Java WebSocket APIAPI文檔結合的本文檔[鏈接]Java WebSocket API規範。本規範定義了一個實現爲了是Java WebSocket API的一個實現必須滿足的要求。該規範是在Java社區進程的規定下制定的。還有測試一個給定的實現是否滿足規範要求的測試兼容性套件(TCK),和實現本規範且通過了TCK的參考實現(RI),該規範定義了WebSocket應用開發的Java標準。雖然本文檔中有開發人員使用Java WebSocketAPI的很多有用的信息,但其目的不是一個開發人員指南。同樣,儘管本文檔中有開發人員創建一個Java WebSocket API實現的很多有用的信息,但其不是一個關於實現所有必需特性的“怎麼做”指南。

1.2.規範的目標

該規範的目標是定義希望在Java平臺上支持websocket編程API的容器的要求。雖然該文檔可能是一個使用規範定義的API的開發人員的有用參考,但該文檔不是一個開發人員指南。

1.3.整個規範中使用的術語

1.3.1. 端點

一個websocket端點(endpoint)是一個表示在兩個連接的節點(peer)之間的一系列的websocket交互的一端的Java組件。

1.3.2. 連接

一個websocket連接(connection)是在兩個使用websocket協議交互的端點之間的網絡連接。

1.3.3. 節點

使用在一個websocket端點上下文中,websocket節點(peer)用於表示與該端點交互的另一個websocket參與者。

1.3.4. 會話

術語websocket會話(session)用於表示在一個端點和單個節點之間的一系列的websocket交互。

1.4.規範約定

該文檔中的關鍵字“必須(MUST)”、“不能(MUST NOT)”、“需要(REQUIRED)”、“應當(SHALL)”、“不得(SHALL NOT)”、“應該(SHOULD)”、“不應該(SHOULD NOT)”、“推薦(RECOMMENDED)”、“可能(MAY)”、和“可選的(OPTIONAL)”由[RFC2119]中的描述解釋。

此外,規範的要求可以使用相符的測試套件進行測試,該測試套件以緊跟着一個用於標識要求的數字的數字WSCWebSocket兼容性)標記,例如“WSC-12”。

Java代碼和實例數據片段的格式如圖1.1所示:圖1.1

Java代碼  收藏代碼
  1. package com.example.hello;  


  2. publicclass Hello {  


  3. publicstaticvoid main(String args[]) {  


  4.        System.out.println("Hello World");  


  5.    }  

一般形式的URI http://example.org/...”和“http://example.com/...”表示應用或上下文相關的URI

此規範的所有部分是標準的、除了示例、註釋和明確標記爲“非標準”的部分。非標準的註釋格式如下所示。

註釋:這是一個註釋。

1.5.專家組成員

本規範是Java社區進程開發的作爲JSR 356[鏈接]。它是JSR 356專家組成員協同工作的結果。完整的公共郵件歸檔可以在這裏找到[鏈接] 。以下是專家組成員:

Jean-Francois Arcand (Individual Member)

Scott Ferguson (Caucho Technology, Inc)

Joe Walnes (DRW Holdings, LLC)

Minehiko IIDA (Fujitsu Limited)

Wenbo Zhu (Google Inc.)

Bill Wigger (IBM)

Justin Lee (Individual Member)

Danny Coward (Oracle)

Rémy Maucherat (RedHat)

Moon Namkoong (TmaxSoft, Inc.)

Mark Thomas (VMware)

Wei Chen (Voxeo Corporation)

1.6.致謝

在開發規範期間,收到了許多審查評論、反饋和建議。尤其感謝:Jitendra KotamrajuMartin MatulaStepan KoprivaPavel BucekJondean HealeyJoakim Erdfelt


2.應用

Java WebSocket應用由websocket端點組成。一個websocket端點是一個表示在兩個節點之間的一個websocket連接的一端的Java對象。

主要有兩種方法可以創建一個端點。第一種方法是實現Java WebSocket API特定的API類與所需的行爲,來處理端點生命週期、消費和發送消息、發佈自己、或連接到一個節點。通常情況下,該規範把這種類型的端點叫做編程式端點。第二種方法是用Java WebSocket API特定的註解來裝飾一個普通的舊Java對象(POJO)。該實現接着獲取這些註解的類並在運行時創建相應的對象把POJO部署爲一個websocket端點。通常情況下,該規範把這種類型的端點叫做註解式端點。當討論這兩種端點中任何一種時:編程式或註解式端點,規範都稱爲端點。

端點參與打開階段握手並建立web socket連接。端點通常將發送和接收各種web socket信息。當web socket連接關閉時端點的生命週期將結束。

2.1.API概述

本節給出了Java WebSocket API的簡要概述,爲之後的詳細要求做準備。

2.1.1. 端點生命週期

一個邏輯websocket端點在Java WebSocketAPI中由Endpoint類的實例表示。實現必須確保每個web socket節點一個實例[WSC 2.1.1-1]。開發人員可以子類化Endpoint類,爲了攔截端點的生命週期事件:一個節點建立連接、一個打開的連接結束和在端點生命週期期間引發的一個錯誤。

除非另有由Java EE組件支持的不同的生命週期,否則websocket實現必須使用每個VM每個應用一個Endpoint類實例來表示每個連接的節點邏輯端點[WSC 2.1.1-2]。第7張描述了所有類型的可以用於創建websocket端點的Java EE組件,其實現可能會創建一個不同數量的實例來表示邏輯端點。Endpoint類的每個實例在通常情況下僅處理來自一個且只有一個節點端點的連接。

2.1.2. 會話

Java WebSocket API使用一個Session類實例模型化在一個端點和它的每個節點之間的一系列的交互。在一個節點和一個端點之間的交互以打開通知開始,其次是一些,可能是零個在端點和節點之間的web socket消息,其次是終止連接的一個關閉通知或錯誤。對於與一個端點交互的每個節點,有唯一一個Session實例表示該交互[WSC 2.1.1-1]對應於那個節點連接的這個Session實例,在其生命週期中的關鍵事件時傳遞給表示邏輯端點的端點實例。

開發人員可以使用通過調用Session對象上的getUserProperties()獲取到的與特定會話的特定應用信息關聯的用戶屬性映射。Websocket實現必須維護這個會話數據供以後訪問使用,直到在端點實例上調用onClose()方法完成爲止[WSC 2.1.2-2]。在那之後,websocket實現允許丟棄開發人員數據。一個選擇池化Session實例的websocket實現可能在這一點上重用相同的Session實例來表示一個新的連接,併爲它分配一個新的唯一的Session id [WSC 2.1.1-3]

是分佈式容器一部分的Websocket實現,在故障轉移的情況下,可能需要從一個節點遷移websocket會話到另一個節點。實現必須維護插入到websocket會話的開發人員數據對象,如果數據標記爲java.io.Serializable [WSC 2.1.2-4]

2.1.3. 接收消息

Java WebSocket API提供了多種方法用於一個端點從它節點的接收消息。開發人員實現最適合他們需要的消息投遞風格的MessageHandler接口的子類型,且通過在對應於節點的Session實例上註冊處理器來從一個特定的節點註冊感興趣的消息。

API限制了每個Session MessageHandlers註冊爲每個本地的websocket消息類型一個MessageHandler [WSC 2.1.3-1]。換句話說,開發人員至多僅能註冊一個傳入的文本消息的MessageHandler、一個傳入的二進制消息的MessageHandler、和一個傳入的pong消息的MessageHandler。如果這個違反了這個限制,websocket實現必須產生一個錯誤[WSC 2.1.3-2]

規範的未來版本可能會取消這個限制。

2.1.4. 發送消息

Java WebSocket API使用一個端點的RemoteEndpoint類的實例模型化會話的每個節點。該類包含了用於從端點到它的節點發送web socket消息的多種方法。

示例

下面是一個服務器端點等待傳入的文本消息的一個示例,且當它獲得到發送它的客戶端的一個消息時立即響應。這個示例是重複的,第一種方法僅使用API類:

Java代碼  收藏代碼
  1. publicclass HelloServer extends Endpoint {  


  2. @Override


  3. publicvoid onOpen(Session session) {  


  4. final RemoteEndpoint remote = session.getRemote();  


  5.    session.addMessageHandler(new MessageHandler.Basic<String>() {  


  6. publicvoid onMessage(String text) {  


  7. try {  


  8.          remote.sendString("Got your message (" + text + "). Thanks !");  


  9.        } catch (IOException ioe) {  


  10.          ioe.printStackTrace();  


  11.        }  


  12.      }  


  13.    });      


  14.  }  


  15. }  


Java代碼  收藏代碼
  1. @WebSocketEndpoint(“/hello”)  


  2. publicclass MyHelloServer {  


  3. @WebSocketMessage


  4. public String doListen(String message) {  


  5. return"Got your message (" + text + "). Thanks !";  


  6.  }  


  7. }  


2.1.5. 關閉連接

如果一個到websocket端點打開的連接因爲一些原因要被關閉,無論是由於從節點收到一個websocket關閉事件的結果,還是因爲底層實現的原因關閉連接,websocket實現必須調用websocket端點的onClose()方法[WSC 2.1.5-1]

待定(TBD已經有一些反饋:onClose()應該僅被調用當節點接收到一個來自另一個節點的關閉幀(close frame)時,和不應該,例如,假如實現的宿主端點由於某些原因(例如,當取消部署應用時)需要自己關閉連接。當連接由容器關閉時,在這方面我們歡迎任何反饋。

建議websocket開發人員使用其他一些方法(例如使用EJB支持websocket)來攔截生命週期事件。

2.1.6. 客戶端和服務器

Websocket協議是雙向協議。一旦建議連接,web socket協議在會話中的兩方之間是雙向的。在websocket客戶端和websocket服務器之間區別只在於雙方通過何種方式連接。在本規範中,我們會說,一個websocket客戶端是一個初始化一個到一個節點的連接的websocket端點。我們會說,一個websocket服務器是一個發佈一個等待來自節點連接的websocket端點。在大多數部署中,一個websocket客戶端將僅連接到一個websocket服務器,且一個websocket服務器將接受來自不同客戶端的連接。

因此,WebSocket API僅辨別端點之間的區別是:來自端點的是websocket客戶端,在配置和安裝階段中的是websocket服務器。

2.2.使用WebSocket註解的端點

Java註解已經成爲廣泛使用的爲Java對象增加部署特性的手段,尤其在Java EE平臺中。Web Socket規範定義了少量的web socket註解,允許開發人員獲取Java類並把它們變成web socket端點。本節

本節給出了簡要概述,爲本規範之後的詳細要求做準備。

2.2.1. 註解式端點

類級別的@WebSocketEndpoint註解表示一個Java類是在運行時變成一個websocket端點。開發人員可以使用value屬性爲端點指定一個URI映射。encodersdecoders屬性允許開發人員指定編碼應用對象到web socket消息和解碼web socket消息到應用對象的類。

2.2.2. Websocket生命週期

方法級別的@WebSocketOpen@WebSocketClose註解允許開發人員在他們的@WebSocketEndpoint註解的Java類中裝飾方法,來指定分別當產生的端點從一個節點接收到一個新的連接時或當從一個節點的一個連接關閉時,它們必須被實現回調[WSC 2.2.2-1]

2.2.3. 處理消息

爲了使註解的端點能處理傳入的消息,方法級的@WebSocketMessage註解允許開發人員表示當收到一個消息時實現必須調用哪一個方法[WSC 2.2.3-1]

2.2.4. 處理錯誤

爲了使註解的端點能處理外部事件引起的錯誤,例如在解碼一個收到的消息,一個註解的端點可以使用@WebSocketError註解標記它的一個方法必須被實現調用並帶有這樣一個錯誤發生時的錯誤消息,[WSC 2.2.4-1]

2.2.5. PingPong

websocket協議中的ping/pong機制作爲檢查連接是否仍處於活動狀態。以下是協議的要求,如果一個websocket實現接收自一個節點傳入的ping消息,它必須儘可能快地用一個包含相同應用數據的pong消息響應那個節點[WSC 2.2.5-1]。希望發送單向pong消息的開發人員可以使用RemoteEndpoint API做這件事情。希望監聽返回的pong消息的開發人員可以爲它們定義一個MessageHandler或使用@WebSocketMessage註解一個方法,該方法規定一個PongMessage作爲它的消息實體參數。在這兩種情況下,如果實現收到一個發送到該端點的pong消息,它必須調用MessageHandler或註解的消息方法[WSC 2.2.5-2]


3.配置

WebSocket應用配置了一些關鍵參數:在容器URI空間中標識一個web socket端點的路徑映射、端點支持的子協議、應用程序需要的擴展。此外,在打開階段握手期間,應用可以選擇執行其他的配置任務,如檢查發出請求的客戶端主機名,或處理cookie。本節詳細介紹了在容器上支持這些配置任務的要求。

客戶端和服務器端點配置包括一系列應用提供的編碼和解碼類,實現必須使用它們在websocket消息和應用定義的消息對象之間轉換[WSC 3-1]

下面是服務器特定的和客戶端特定的配置選項定義。

3.1.服務器配置

爲了部署一個編程式端點到對客戶端連接可用的URI空間,容器需要一個ServerEndpointConfiguration實例。WebSocket API提供了該接口的一個默認實現[WSC-3.1-1]。這些配置對象使用默認的策略來協商打開階段握手,並將建立(或不建立)每一個websocket連接。

3.1.1. URI 映射

默認服務器配置的URI映射策略是打開階段握手URI通過以下方式匹配一個端點的相對路徑:

如果端點的相對路徑是一個相對URI,當且僅當有一個URI完全匹配[WSC 3.1.1-1]

相對路徑是一個請求URI匹配的URI模板(level-1),當且僅當請求URI是一個URI模板的展開版本。[WSC 3.1.1-2]

實現必須不建立連接,除非有一個匹配[WSC 3 1 1 3]

3.1.2. 子協議協商

默認服務器配置必須在創建時提供按優先順序排列的一系列支持的協議。在子協議協商期間,此配置檢查客戶端提供的子協議列表,並選擇它支持的包含在客戶端提供的列表中的第一個子協議,或者沒有如果沒有匹配的[WSC-3.1.2-1]

3.1.3. 擴展變更

在打開階段握手時,客戶端提供了一系列它想使用的擴展。默認服務器配置從這些擴展中選擇一個它支持的,並以客戶端所請求的相同順序放置它們 [WSC-3.1.3-1]

3.1.4. 來源檢查

默認服務器配置檢查Origin頭提供的主機名,如果主機名不能被驗證則握手失敗[WSC-3.1.4-1]

3.1.5. 握手變更

默認服務器配置除了上邊描述的並沒有改變打開階段握手處理 [WSC-3.1.5-1]

開發人員可能希望定製上述規定的配置和握手協商策略。爲了做到這一點,他們可能會提供他們自己的ServerEndpointConfiguration實現,或者通過直接實現它,或者子類化默認實現。

例如,他們可能希望更多地介入握手處理。他們可能希望使用Http Cookie來跟蹤客戶端,或在握手響應中插入應用特定的頭。爲了做到這一點,他們可能覆蓋ServerEndpointConfiguration modifyHandshake()方法,在那裏他們可以有握手的HandshakeRequestHandshakeResponse的全部訪問權限。

他們可能希望提供一個更復雜的方法來映射URI到端點,例如通過web socket註解的基於shcemeURI-模板(參見第4註解)。

3.1.6. 不同實例間的狀態共享

開發人員可以實現ServerEndpointConfiguration以保存應用狀態,這將是非常有用的對所有Endpoint實例同一個邏輯端點的情況。

3.2.客戶端配置

爲了連接一個websocket客戶端端點到它對應的websocket服務器端點,實現需要配置信息。除了編碼器和解碼器列表,Java WebSocket API需要以下屬性:

3.2.1. 子協議

默認客戶端配置使用開發人員提,它想要使用的供的子協議列表,按照優先順序來發送,在打開階段握手中想要使用的它制定的子協議的名字[WSC-3.2.1-1]

3.2.2. 擴展

默認客戶端配置必須使用開發人員提供的擴展列表來發送,按照優先順序來發送,在打開階段握手中它制定的它想要使用的擴展,包括參數。

3.2.3. 客戶端配置變更

一些客戶端可能希望以適應的方式在客戶端應用中提供子協議列表或擴展列表,或打開階段握手的客戶端與服務器交互的其他方面。開發人員可能提供他們自己的覆蓋默認API行爲的ClientEndpointConfiguration實現,爲了對其進行定製以滿足特定應用的要求。


4.註解

本節包含了一個在Java WebSocket API中的註解語義的完整規範。

4.1.@WebSocketEndpoint

這個類級別的註解表示它裝飾的Java類必須被實現部署爲一個websocket服務器端點並使其在web socket實現的URI-空間中可用[WSC-4.1-1]。該類必須有一個public無參構造器,且另外可能符合第7章中列出的類型之一。

4.1.1 value

Value屬性必須是一個Java字符串,其是一個部分URIURI-模板(level-1),以“/”開頭。URI-模板的定義,請參見[6]。實現使用value屬性來部署端點到web socket實現的URI空間。實現必須把value作爲相對於web socket實現的根URI,用來確定是否與一個傳入的打開階段握手的請求的請求URI匹配[WSC-4.1.1-2]。如果value是一個部分URI,請求URI匹配,當且僅當精確匹配。如果value是一個URI模板(level-1),請求URI匹配,當且僅當請求URI是一個URI模板的擴展版本。Value屬性是強制的,在部署時,實現必須拒絕缺少或殘缺的路徑[WSC-4.1.1-3]

Java代碼  收藏代碼
  1. @WebSocketEndpoint("/bookings/{guest-id}")  


  2. publicclass BookingServer {  


  3. @WebSocketMessage


  4. publicvoid processBookingRequest(  


  5. @WebSocketPathParam("guest-id") String guestID,  


  6.    String message,  


  7.    Session session) {  


  8. // process booking from the given guest here


  9.  }  


  10. }  


在這種情況下,客戶端可以使用任意URI連接到這個端點:

/bookings/JohnSmith

/bookings/SallyBrown

/bookings/MadisonWatson

然而,如果端點註解是@WebSocketEndpoint("/bookings/SallyBrown"),那麼只有一個客戶羣請求到/bookings/SallyBrown將能夠連接到這個web socket端點。

如果在value屬性中使用URI-模板,開發人員可以使用@WebSocketPathParameter取出變量路徑片段,如下所述。

包含多於一個註解端點的應用可能不經意地使用相同的相對URIWebsocket實現在部署時必須拒絕這樣一個應用,並帶有一個他不能解決的重複路徑的錯誤提示消息[WSC-4.1.1-4]

應用可能包含一個映射到一個路徑的端點,該路徑是URI模板的擴展形式,該路徑也被相同應用中的另一個端點使用。在這種情況下,應用是有效的。在運行時,如果websocket實現接收到一個精確匹配該相對URI的打開階段握手,它必須匹配那個,即使在別處它是一個URI-模板的擴展形式[WSC-4.1.1-5]

規範的未來版本可能會允許更高級的URI模板。

4.1.2. encoders

encoders屬性包含一個(可能是空)爲該端點充當編碼器組件的Java類列表。這些類必須實現某種形式的Encoder接口,並具有public無參構造器和在這個websocket端點所在的應用的classpath內是可見的。實現必須按照編碼器嘗試編碼匹配參數化類型的應用對象當它們試圖使用RemoteEndpoint API發送時。實現必須使用第一個匹配列表中類型的編碼器[WSC-4.1.2-2]

4.1.3. decoders

decoders屬性包含一個(可能是空)爲該端點充當解碼器組件的Java類列表。

些類必須實現某種形式的Decoder接口,並具有public無參構造器和在這個websocket端點所在的應用的classpath內是可見的。實現必須嘗試使用列表中適合於本地websocket消息類型的解碼器解碼web socket消息,並以解碼的對象形式傳遞消息到webscoket端點[WSC-4.1.3-1]。在擁有它的Decoder實現上,實現必須使用解碼器的willDecode()方法來決定是否Decoder將匹配傳入的消息 [WSC-4.1.4-2]

4.1.4. subprotocols

subprotocols參數包含一個(可能爲空)該端口支持的子協議名字的字符串列表。實現必須在打開階段握手使用該列表來協商用於建立連接的所需的子協議[WSC-4.1.4-1]

4.1.5. 配置

該可選的配置屬性使開發人員能表明他想要的websocket實現使用一個定製的DefaultServerConfiguration子類。如果提供了一個,websocket實現必須使用這個來配置端點[4.1.5-1]。開發人員可能使用這個技術在端點的不同實例間狀態共享,除了定製的打開階段握手。

待定(TBD):可能還添加在註解中指定擴展的能力?

4.2.@WebSocketClient

這個類級別的註解表示它裝飾的Java類被部署爲一個將連接到駐留在web socket服務器的web socket端點的websocket客戶端端點。該類必須有public無參構造器,且另外可能符合第7章中列出的類型之一。

4.2.1. encoders

encoders屬性包含一個(可能是空)爲該端點充當編碼器組件的Java類列表。這些類必須實現某種形式的Encoder接口,並具有public無參構造器和在這個websocket端點所在的應用的classpath內是可見的。實現必須按照編碼器嘗試編碼匹配參數化類型的應用對象當它們試圖使用RemoteEndpoint API發送時。實現必須使用第一個匹配列表中類型的編碼器[WSC-4.1.2-2]

4.2.2. decoders

decoders屬性包含一個(可能是空)爲該端點充當解碼器組件的Java類列表。這些類必須實現某種形式的Decoder接口,並具有public無參構造器和在這個websocket端點所在的應用的classpath內是可見的。實現必須嘗試使用列表中適合於本地websocket消息類型的解碼器解碼web socket消息,並以解碼的對象形式傳遞消息到webscoket端點[WSC-4.2.2-1]。如果Decoder實現有這個方法,實現必須使用解碼器的willDecode()方法來決定是否Decoder將匹配傳入的消息 [WSC-4.2.2-2]

4.2.3. subprotocols

subprotocols參數包含一個(可能爲空)該端口將支持的子協議名字的字符串列表。實現必須在打開階段握手使用該列表來協商用於建立連接的所需的子協議[WSC-4.2.3-1]

待定(TBD):我們可能添加在註解中指定擴展的能力。

4.3.@WebSocketPathParam

這個註解用於在一個裝飾着任何@WebSocketMessage@WebSocketError@WebSocketOpen@WebSocketClose註解的帶註解的端點上註解一個或多個方法參數。這些參數允許的類型是StringJava原子類型、或它的包裝版本。任何使用該註解的其他類型的註解是錯誤的,實現必須在部署時報告[WSC 4.3-1]。這個註解的value屬性必須存在,否則實現必須拋出一個錯誤[WSC 4.3-2]。如果這個註解的value屬性匹配一個在@WebSocketEndpoint 註解的那個端點上使用URI模板的一個元素的變量名,那麼實現必須在方法被調用時把調用web socket幀連接的請求URI的路徑片段值關聯到它註解的value參數。[WSC 4.3-3]。否則,使用這個註解註解的String參數值,實現必須設置爲null。關聯必須遵循下列規則:

如果參數是String,容器必須使用路徑片段的值[WSC 4.3-4]

如果參數是一個Java原子類型或它的裝箱版本,容器必須使用路徑片段字符串來構造類型相同的結果,假如該類型有public的一個String參數的構造器來獲得裝箱類型,且如果必要降低爲原子類型[WSC 4.3-5]

如果容器不能適當地解碼路徑片段爲註解的路徑參數,那麼容器必須發出DecodeException異常到web socket包含的路徑片段的錯誤處理方法[WSC 4.3-6]

Java代碼  收藏代碼
  1. @WebSocketEndpoint("/bookings/{guest-id}")  


  2. publicclass BookingServer {  


  3. @WebSocketMessage


  4. publicvoid processBookingRequest(  


  5. @WebSocketPathParam("guest-id") String guestID,  


  6.     String message,  


  7.     Session session) {  


  8. // process booking from the given guest here


  9.  }  


  10. }  


在這個例子中,如果客戶端使用URI /bookings/ JohnSmith連接到這個端點,那麼guestID參數的值將爲“JohnSmith”。

下面是一個關於路徑參數是一個Integer的例子:

Java代碼  收藏代碼
  1. @WebSocketEndpoint("/rewards/{vip-level}")  


  2. publicclass RewardServer {  


  3. @WebSocketMessage


  4. publicvoid proce***eward(  


  5. @WebSocketPathParam("vip-level") Integer vipLevel,  


  6.     String message,  


  7.     Session session) {  


  8. // process reward here


  9.  }  


  10. }  


4.4.@WebSocketOpen

該註解是一個方法級別註解。當一個新的客戶端連接到這個端點時該註解定義的包裝方法將被調用。在連接建立後容器通知該方法[WSC-4.4-1]。包裝的方法僅能有一個可選的Session參數、一個可選的EndpointConfiguration參數和零個到N@WebSocketPathParam 註解的String參數。如果Session參數存在,實現必須傳入與新的連接關聯的最新創建的Session[WSC-4.4-2]。有一個方法上使用了該註解的任何Java類沒有遵循這些規則,可能不被實現部署並向部署人員報告錯誤[WSC-4.4-3]

4.5.@WebSocketClose

該註解是一個方法級別註解。當一個新的客戶端從該端點斷開時,該註解定義的保證方法將被調用。在連接被關閉之前容器通知該方法[WSC-4.5-1]。包裝的方法僅能有一個可選的Session參數和零個到N@WebSocketPathParam 註解的String參數。如果Session參數存在,實現必須傳入與連接關聯的即將結束的Session[WSC-4.5-2].。如果該方法本身拋出了一個錯誤,實現必須把這個錯誤連同會話一起傳遞到端點的onError()方法[WSC-4.5-3]。有一個方法上使用了該註解的任何Java類沒有遵循這些規則,可能不被實現部署並向部署人員報告錯誤[WSC-4.5-4]

4.6.@WebSocketError

該註解是一個方法級別註解。該註解定義了每當到這個端點的任何連接生成了一個錯誤時被調用的包裝方法。該包裝方法僅能有可選的Session參數,必須的Throwable參數和零個到N@WebSocketPathParam 註解的String參數。如果有Session參數,實現必須傳入出現錯誤的連接的Session[WSC-4.6-1]。容器必須以Throwable參數傳入錯誤到這個方法。[WSC-4.6-2] 使用該註解註解在一個方法上的任何Java類如果不遵守這些規則,可能不能被實現部署且報告錯誤給部署人員。[WSC-4.5-3]

4.7.@WebSocketMessage

該註解是一個方法級別的註解。當接收到一個傳入的消息時該註解定義的包裝方法將被調用。它裝飾的方法可以具有許多形式:

它的方法參數可以包括

a)任何下列選擇之一

- String用於整個文本消息處理

- Stringboolean用於部分文本消息處理

- byte[]ByteBuffer用於整個二進制消息處理

- byte[]boolean對,或ByteBufferboolean用於部分二進制消息處理

- 任何可解碼的對象參數(端點配置的Decoders確定的)

- PongMessage用於處理pong消息

b) 零個到N個使用@WebSocketPathParam註解的StringJava原子類型參數

c) 可選的Session參數

這些參數可以以任何順序列出。

該方法可以有一個非-void的返回值類型,在這種情況下,web socket運行時必須解釋這個爲web socket消息並返回給節點。此返回值類型允許的數據類型,除了void,是

- StringByteBufferbyte[]、任何Java原子類型或等價的類和有一個解碼器的任何類型。

任何@WebSocketMessage註解的方法,不符合上邊描述的形式是無效的。websocket實現必須不部署這樣的端點,並如果嘗試部署這樣註解的端點,必須發出一個部署錯誤[WSC-4.7-1]

每一個websocket端點可能僅有一個消息處理方法用於每個本地webscoket消息格式:文本、二進制和pongWebsocket實現必須不部署這樣的端點,且如果嘗試部署這樣一個註解的端點,必須發出一個部署時錯誤[WSC-4.7-2]

maxMessageSize

maxMessageSize屬性允許開發人員指定它註解的方法將能處理的以字節爲單位的最大大小的消息,-1表示不限制。默認是-1

如果傳入的消息超過最大消息大小,實現必須報告這是一個錯誤[WSC-4.7-3]


5.異常處理和線程

WebSocket API實現可以採用多種線程策略以提供一個可伸縮的實現。該規範目的是允許一系列的策略。然而,該實現必須滿足一定的線程要求,以便爲開發人員提供一個用於它們應用的一致的線程環境。

除非Java EE組件支持不同的生命週期(參考第7章),否則容器必須每個節點使用一個唯一的端點實例[WSC-5.1-1]。在所有情況下,實現必須不在每個節點的多個線程中同時調用一個端點實例[WSC-5.1-2]。實現可能不調用在一個端點上的close方法直到open方法完成之後[WSC-5.1-3]

這個可以保證一個websocket端點實例是從不被每個節點的多個容器線程同時調用[WSC-5.1-4]

如果以片段形式收到一個傳入的消息,容器必須確保相關的onMessage()調用是按順序調用的,且既沒有與相同消息的片段交錯也沒有與其他消息交錯 [WSC-5.1.5]

待定(TBD):可能需要爲onMessage()定義一些關於容器創建回調線程和他們如何與用於(異常)發送的回調線程交互。

5.2.錯誤處理

該規範定義有三類錯誤(受查和非受查Java異常)。

5.2.1. 部署錯誤

這是是在部署一個包含websocket端點的應用期間引起的錯誤。這些錯誤有些是在部署應用期間容器的故障引起的結果。例如,容器可能沒有足夠的計算資源來部署指定的應用。在這種情況下,容器在部署過程期間必須提供一個錯誤提示消息給開發人員[WSC-5.2.1-1]。其餘的錯誤,由殘缺的websocket應用引起的結果。第4章提供了幾個殘缺的websocket端點的例子。在這種情況下,容器在部署過程期間必須提供一個錯誤提示消息給部署人員[WSC-5.2.1-2]

在這兩種情況下,在部署過程期間引起的一個部署錯誤必須停止應用的部署,在引起錯誤之前部署的任何形式良好的端點必須從服務中移除且不再有來自應用的websocket端點可以被容器部署,即使他們是有效的[WSC-5.2.1-3]

如果部署錯誤發生在開發人員編程控制下,例如,當時有WebSocketContainer API部署一個客戶端端點,部署錯誤必須由容器通過使用一個DeploymentException實例報告給開發人員[WSC-5.2.1-4]。在這種情況下,容器可以選擇用語精確的錯誤消息。

如果部署錯誤發生在實現管理的部署期間,例如,由於部署一個容器部署端點所在的WAR文件由於掃描WAR文件,作爲容器特定的部署過程的一部分,部署錯誤必須由實現被報告給部署人員[WSC-5.2.1-5]

5.2.2. websocket應用代碼產生的錯誤

在一個websocket端點運行期間引起的所有錯誤必須被websocket實現捕獲[WSC-5.2.2-1]。這些錯誤的例子包括端點使用的Decoders生成的受查異常,端點使用的消息處理代碼產生的運行時錯誤。如果websocket端點提供了一個錯誤處理方法,無論是在編程式端點的情況下通過實現onError()方法,還是在註解式端點情況下使用@WebSocketError註解,實現必須以錯誤調用錯誤處理方法[WSC-5.2.2-2]

如果開發人員沒有在產生錯誤的端點上提供一個錯誤處理方法,這表示實現,開發人員不希望處理這樣的錯誤。在這些情況下,容器必須使這個信息可供以後分析,例如通過記錄它[WSC-5.2.2-3]

如果一個端點本身的錯誤處理方法產生運行時錯誤,容器必須使這個信息可供以後分析[WSC-5.2.2-4]

待定(TBD):是否他們希望容器應該允許取消部署生成太多錯誤的應用?在這方面我們歡迎反饋。

5.2.3. 容器和/或底層連接產生的錯誤

在端點運行期間可能出現各種運行時錯誤。這些可能包括中斷的底層連接、偶爾的通信錯誤處理傳入和傳出消息、或與節點通信的致命錯誤。實現或它們的管理員判斷這樣的錯誤是否是致命的,正確運行的端點可能關閉端點連接,使用onClose()方法嘗試通知兩個參與者。容器判斷這樣的錯誤是否是非致命的,正確運行的端點可能允許端點繼續運行,但必須在消息處理期間報告錯誤,或者作爲檢查異常由一個發生操作返回,或者記錄錯誤用於以後分析[WSC-5.2.3-1]


6.打包和部署

Java WebSocket應用使用Java平臺通常的約定打包。

6.1.JDK上的客戶端部署

用於web socket應用的類文件和任何如Java WebSocket客戶端應用的應用資源被打包爲JAR文件,除了如文本或圖像文件的任何資源之外它需要的。

客戶端容器不需要自動掃描JAR文件尋找web socket客戶端端點並部署它們。

使用ContainerProvider類獲得一個到WebSocketContainer的引用,開發人員使用WebSocketContainer上的connectToServer() API部署編程式端點和註解式端點。

6.2.Web容器上的應用部署

類文件和任何如文本和圖像文件的資源被打包進Java EE定義的WAR包,或者直接位於WEB-INF/classes下或打包爲一個JAR文件並位於WEB-INF/lib下。

Java WebSocket實現必須使用定義在[Servlet 3.0] 中的web容器掃描機制在部署時來發現包含在WAR文件中的註解式和編程式端點[WSC-6.2-1]。此外,websocket實現必須使用web socket掃描機制來發現打包在WAR文件(或在任何它的子JAR文件)中的ServerApplicationConfiguration接口的實現[WSC-6.2-2]

如果WAR文件不包含ServerApplicationConfiguration實現,它必須部署它掃描定位的所有端點[WSC-6.2-3]

如果掃描的WAR文件定位到一個或多個ServerApplicationConfiguration實現,websocket實現必須實例化每一個它發現的ServerApplicationConfiguration類,它必須把掃描的包含它的(頂層EAR或包含的JAR)歸檔的結果傳遞到它的方法[WSC-6.2-4]

該集合是通過調用web socket實現必須部署的ServerApplicationConfiguration 類集合的getEndpointConfigurationClasses() getAnnotatedEndpointClasses()獲得的所有結果的合併[WSC-6.2-5]

注意:這意味着開發人員容易地部署WAR文件中的所有端點,通過簡單地把用於它們的類文件捆綁到WAR包中。這也意味着通過提供一個iehuo多個ServerApplicationConfiguration實現類,開發人員可以精確地控制哪些WAR文件中的端點是被部署。通過從掃描中(參考Servlet3.08.2.1節)排除某些JAR文件,這也使得開發人員可以限制一個潛在地漫長地掃描過程。最後一種情況可能是可取的,一個WAR文件包含很多JAR文件,開發人員知道其不包含任何websocket端點。

6.3.在獨立的websocket服務器容器中的應用部署

該規範推薦獨立的websocket服務器容器(即那些不包括一個servlet容器的)定位任何websocket服務器端點和應用包中的ServerApplicationConfiguration類並部署配置類返回的所有服務器端點集合。不過,如果他們希望,獨立的websocket服務器容器可以使用其他的實現技術來部署端點。

6.4.Websocket 服務器路徑

WebSocket實現包括服務器功能必須爲websocket定義一個根或URI空間。所謂的websocket根,就是所有相對websocket路徑的URI都是相對的。如果websocket服務器不包括Servlet APIwebsocket服務器可以選擇websocket根本身。如果websocket服務器包含Java Servlet APIwebsocket根必須與web應用的servlet上下文根是相同的[WSC-6.4-1]

6.5.平臺版本

Java平臺最低版本是:

Java SE 版本7,用於Java WebSocket客戶端API [WSC-35]

Java EE 版本6,用於Java WebSocket服務器API [WSC-36]


7.Java EE環境

7.1.Java EE環境

Java EE平臺支持時,支持Web Socket應用還有一些額外的要求。

7.1.1. 使用Java EE組件創建端點

除了能應用WebSocket註解到Java類,websocket實現還必須支持使用以下的JavaEE組件創建websocket端點[WSC-7.1.1-1]

有狀態會話EJB

單例EJB

CDI託管bean

(待定:CDI託管Bean允許的範圍)

7.2.Http Session與通過身份認證的狀態的關係

這通常是有用的,對於開發人員嵌入web socket服務器端點到一個更大的web應用,能夠在每個客戶端基礎上在web資源(如JSPJSFServlet)和服務客戶端的web socket端點之間共享信息。由於web socket連接是隨着http請求初始化的,所以在客戶端正運行的HttpSession和在該HttpSession內建立的任何web socket之間存在一個關聯。該API允許在打開階段握手期間訪問關聯到相同客戶端的唯一HttpSession [WSC-7.2-1]

類似地,如果打開階段握手請求已經通過了服務器的身份驗證,則打開階段握手 API允許開發人員查詢請求的用戶Principal。如果已經建立與請求客戶端的連接,web socket實現把出現在打開階段握手時的用戶Principal看作爲與websocket Session關聯的用戶Principal[WSC-7.2-2]

在一個websocket端點是web應用中的受保護的資源的情況下(參考第8章),就是說,需要一個授權用戶訪問它,因此,websocket實現必須確保在底層實現已經決定驗證身份不再有效之後websocket端點不再保持與它的節點連接[WSC-7.2-3]

這可能發生,例如,如果用戶退出了包含的web應用,或如果身份驗證超時,或由於其他一些原因無效的。在這種情況下,websocket實現必須立即使用websocket關閉狀態碼1008關閉連接[WSC-7.2-3]

另一方面,如果websocket端點不是web應用的一個受保護資源,那麼在打開階段握手建立的連接過程中用戶身份可能失效或在websocket運行期間沒有websocket實現需要關閉連接情況下得到改變。


8.服務器安全

Web Socket端點使用web容器安全模型來保護。這樣做的目的是爲了便於web socket開發人員聲明訪問一個web socket服務器端的是否需要經過身份認證,和誰可以訪問它,和是否需要加密連接或不需要。映射到一個給定的ws:// URI(如在第3和第4章中描述的)的web socket是受在部署描述符中列出的具有相同主機名、端口和路徑的http:// URI保護的,因爲這是它的打開階段握手的URI

因此,web socket開發人員可以指定一個身份認證方案,授予訪問的用戶角色和到它們的web socket端點的傳輸保證。

8.1. web socket身份認證

該規範沒有定義web socket本身也可以進行身份認證的機制。相反,通過以servlet定義的安全機制爲基礎,需要身份認證的web socket在進行身份認證以前必須依賴於試圖初始化一個連接的打開階段握手請求。通常,這將由包含web socketweb應用中的一個Http身份驗證(可能是基本的或基於表單的)在web socket的打開階段握手之前執行。

如果一個客戶端向一個受安全機制保護的web socket發送了一個未經身份認證的打開階段握手請求,web socket實現必須返回401(未授權)響應到打開階段我去請求並不會初始化web socket連接[WSC-8.1-1]

待定添加/重用Servlet安全註解定義web socket授權。

8.2.web socket授權

web socket授權可以通過往它打包在的web應用的web.xml添加一個<security-constraint>元素。安全約束中使用的url-pattern必須由容器使用來匹配web socket的打開階段握手的請求URI[WSC-82]。實現必須解釋除了GET(或默認,缺少的)之外的任何http-method不應用到web socket[WSC-8.2-1]

8.3.傳輸保證

NONE傳輸保證必須由容器解釋爲到允許未加密的ws:// web socket的連接[WSC-8.3-1]CONFIDENTIAL傳輸保證必須由實現解釋爲僅允許在加密(wss://)的連接之上訪問web socket[WSC-8.3-1]。這可能需要一個預先身份認證請求。

ToDo 添加示例


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章