Grizzly FilterChains and Filters
FilterChains and Filters
在前面的部分中,我們提到了Processor,它的角色-處理發生在Grizzly * Connection * s上的 I/O 事件。
所述FilterChain是 Grizzly 中使用的最有用的類型的處理器。
根據名稱所描述的那樣,FilterChain是 Filters 的鏈。每個Filter代表要執行的處理工作的一個單元,
其目的是檢查和/或修改由FilterChainContext表示的事務的狀態。
為了讓您了解FilterChain的外觀,下面是FilterChain的示例,該示例實現了HTTP服務器邏輯:
- TransportFilter 負責從網絡連接讀取數據到 Buffer,并將數據從緩沖區寫入到網絡連接
- HttpFilter 負責 Buffer <-> HttpPacket 轉換(雙向)
- HttpServerFilter負責處理請求 HttpPackets 并生成響應 HttpPackets,
并將它們以相反的方向(HttpServerFilter-> HttpFilter-> TransportFilter)發送回FilterChain。
那么,如果我們要實現HTTPS服務器呢?這很簡單:
我們僅添加一個SSLFilter,負責對SSL安全數據進行編碼/解碼。
如我們所見,在處理任何I / O事件期間,FilterChain中的過濾器將按特定順序執行。
重要的是要記住,除了WRITE事件外,大多數 I/O事件都是從第一個過濾器到最后一個處理(從上面的模式從左到右)處理的,
而WRITE事件的處理是從鏈中的最后一個過濾器開始到第一個(從右到左)處理的。上面的模式)。
讓我們定義一些術語以使以下描述更清楚:
- Upstream 上游, 從此過濾器到鏈中最后一個過濾器的方向(在以上架構中從左到右);
- Downstream 下游,從此過濾器到鏈中第一個過濾器的方向(在上述架構中從右到左);
讓我們看一下 FilterChain 可以處理哪些 I/O 事件,為此,我們可以看一下 Filter 接口方法:
public NextAction handleRead(FilterChainContext ctx) throws IOException;public NextAction handleWrite(FilterChainContext ctx) throws IOException;public NextAction handleConnect(FilterChainContext ctx) throws IOException;public NextAction handleAccept(FilterChainContext ctx) throws IOException;public NextAction handleClose(FilterChainContext ctx) throws IOException;所以 I/O 事件有
- READ:可以從連接(Connection)中獲得數據,可以對其進行讀取和處理;
- WRITE: 數據將被寫入到連接(Connection)中,并且Filter可能負責轉換數據表示形式,例如HttpPacket- > 上面模式中的Buffer;
- CONNECT:新客戶端連接已連接;
- ACCEPT(僅限TCP):新的客戶端連接已被服務器接受連接(TCPNIOServerConnection);
- CLOSE:連接已關閉(本地或對端);
重要的是要記住,特定連接上的相同 I/O 事件是串行處理的。例如,如果我們在連接 “A” 上處理 READ I/O 事件,
則在上一個 READ I/O 事件的處理完成之前,Grizzly 將永遠不會開始在同一連接 “A” 上處理另一個 READ I/O 事件。
如果用戶決定擁有 I/O 事件處理的所有權,則仍應遵守串行事件處理的"規則"。
另外,FilterChain 篩選器(filters) 能夠啟動和處理自定義事件通知。事件發起者可以選擇通過FilterChain在上游或下游發出事件,例如:
public NextAction handleRead(FilterChainContext ctx) throws IOException {// Here we decide to notify downstream Filters 這里我們決定通知下游過濾器 ctx.notifyDownstream(new OneEvent(...));// Notify upstream Filters 通知上游過濾器 ctx.notifyUpstream(new AnotherEvent(...)); }FilterChain 中的過濾器(Filters) 可以通過實現以下方法來攔截和處理自定義事件:
public NextAction handleEvent(FilterChainContext ctx, FilterChainEvent event) throws IOException;如我們所見,每個 Filter “handle” 方法都有 FilterChainContext 參數,并返回 NextAction 結果。
FilterChainContext表示一個上下文(狀態)Context(status),與特定 Connection 上特定 I/O 事件的處理相關聯,
因此其生命周期綁定到單個I / O事件的處理。
FilterChainContext包含以下狀態信息:
Connection
發生 Connection I/O 事件;
Address
對等地址。在大多數情況下,它返回與 Connection.getPeerAddress() 相同的值,
除非在我們處理未綁定 UDP 連接上的 READ 事件的情況下。在這種情況下,FilterChainContext.getAddress()
將返回發送數據的對等方的地址;
Message
正在處理的消息。這是過濾器在 I/O 事件處理期間可能更改的唯一值。通常在傳入/傳出消息解析/序列化期間使用它。
每個過濾器都能夠獲取初始消息數據,將其轉換為不同的表示形式,將其放回原處,并將處理傳遞給鏈中的下一個過濾器。
例如,當處理 READ 事件時,HttpFilter從FilterChainContext獲取消息作為Grizzly Buffer,將其轉換為HttpPacket,
將 HttpPacket 設置回 FilterChainContext 消息,然后將控制權傳遞給 HttpServerFilter,
后者將從 FilterChainContext 獲取 HttpPacket 并對其進行處理。
除了保持狀態外,FilterChainContext還支持常用的 I/O 操作:
Read
ReadResult readResult = ctx.read();此操作從該過濾器(不包括)上游的鏈中的第一個過濾器(包括)開始執行阻塞的FilterChain讀取。
當對 READ I/O 事件的處理將到達當前 Filter 時,該操作將返回結果,并且 FilterChain 將要調用此 Filter的handleRead(…)操作。
Write
ctx.write(message);// or ctx.write(message, completionHandler)// orctx.write(address, message, completionHandler); //Unbound UDP only此操作從第一個過濾器(含)之后的此過濾器(不含)開始執行無阻塞 FilterChain 寫入。
此操作從此 Filter(獨占)開始在 FilterChain 上啟動 WRITE I/O 事件的處理。
Flush
ctx.flush(); //or ctx.flush(completionHandler);此操作初始化并通知下游篩選器(filters)有關特殊的 TransportFilter.FlushEvent 的信息,
以便每個篩選器都能夠處理此事件,并確保所有緩存的數據均已寫入Connection。
Event notification
ctx.notifyUpstream(event); // or ctx.notifyDownstream(event);該操作將特定FilterChainEvent通知給FilterChain中的所有上游/下游Filter 。
NextAction
如前所述,在處理 I/O 事件期間,除了WRITE事件(從最后一個Filter到first進行處理)外,
FilterChain 從頭到尾依次調用Filters。同時,過濾器可以通過返回不同類型的 NextAction 來更改默認的 I/O 事件處理順序:
StopAction
return ctx.getStopAction();指示FilterChain停止處理此I / O事件。通常,如果沒有足夠的數據來繼續FilterChain處理,或者它是鏈中的最后一個Filter,則返回StopAction。
StopAction可以參數化:
return ctx.getStopAction(incompleteChunk); // or return ctx.getStopAction(incompleteChunk, appender);StopAction中的incompleteChunk意味著沒有足夠的數據來繼續FilterChain處理。隨著更多數據可用,但在FilterChain調用Filter之前,它將檢查Filter在上一次調用之后是否存儲了任何數據。如果存在一個不完整的塊,它將新數據追加到存儲的數據中,并將結果作為FilterChainContext消息傳遞。
注意:incompleteChunk應該是“可附加的”,因此FilterChain將知道如何將新的數據塊附加到存儲的塊中。因此,incompleteChunk應該實現org.glassfish.grizzly.Appendable或org.glassfish.grizzly.Appender作為附加參數。
InvokeAction
return ctx.getInvokeAction();指示FilterChain根據自然執行順序在鏈中運行下一個Filter。
可以使用 incompleteChunk 參數創建InvokeAction :
這會指示FilterChain存儲incompleteChunk并像執行非參數化版本一樣繼續執行FilterChain。
此功能對于從源緩沖區解析一條消息或幾條消息并發現存在剩余數據量不足以轉換為應用程序消息的情況特別有用。因此,
開發人員可以繼續使用已解析的消息進行FilterChain處理,并存儲incompleteChunk余數。隨著更多數據可用,
但在FilterChain再次調用Filter之前,它將檢查Filter在上一次調用之后是否存儲了任何數據。
如果存在一個不完整的塊,它將新數據追加到存儲的數據中,并將結果作為FilterChainContext消息傳遞。
注意:incompleteChunk應該是“可附加的”,因此FilterChain將知道如何將新的數據塊附加到存儲的塊中。
因此,incompleteChunk應該實現org.glassfish.grizzly.Appendable或org.glassfish.grizzly.Appender作為附加參數。
另一種選擇是創建具有的InvokeAction unparsedChunk 參數:
return ctx.getInvokeAction(unparsedChunk);這指示FilterChain存儲unparsedChunk并像執行非參數化版本一樣繼續執行FilterChain。與上述“ incompleteChunk”情況不同,
這次我們不知道unparsedChunk是否具有足夠的數據可轉換為應用程序消息。一旦FilterChain執行完成,將恢復鏈中最新的Filter的unparsedChunk,將立即從存儲了unparededChunk的Filter開始重新初始化FilterChain處理。
對于從源緩沖區解析消息并發現緩沖區包含剩余部分(可能包含也可能不包含更多消息)的情況,此功能特別有用。
這使開發人員可以提取第一條消息,并在當前消息處理完成后保存其余要處理的消息。
RerunFilterAction
return ctx.getRerunFilterAction();指示 FilterChain 重新運行一次此 Filter。這對于簡化 I/O 事件處理代碼并避免遞歸很有用。
SuspendAction
return ctx.getSuspendAction();指示 FilterChain 終止(離開)當前線程中的 I/O 事件處理。用戶將可以通過調用來恢復 I/O 事件處理.
- ctx.resume(): 在暫停的同一過濾器上恢復處理。
- ctx.resume(NextAction): 在被暫停的相同Filter上恢復處理,但不將控制權傳遞給Filter-它模擬Filter的處理完成,就像它返回NextAction作為結果一樣
- ctx.resumeNext(): 在掛起的過濾器旁邊的過濾器處恢復處理。 和 ctx.resume(ctx.getInvokeAction()) 相同.
請注意,在返回 SuspendAction 之后,在繼續 I/O 事件處理之前,Grizzly 將不會在同一Connection上初始化相同的 I/O 事件處理。
例如,如果我們在 READ 事件處理期間返回 SuspendAction,則 Grizzly 不會通知 FilterChain 有關同一 Connection 上的任何新數據的通知,
直到已暫停事件的 READ 事件完成為止。
ForkAction (was SuspendStopAction)
return txt.getForkAction();這個動作是非常相似的 SuspendAction,除了一件重要的事情。獲取 ForkAction 之后,Grizzly將繼續監聽Connection上的相同I / O事件,并在發生時通知FilterChain。
使用NextAction時要格外小心,以確保兩個或多個線程不會同時處理同一I / O操作。
總結
以上是生活随笔為你收集整理的Grizzly FilterChains and Filters的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机故事英语版,计算机英文原版
- 下一篇: MySql 模糊查询