• 沒有找到結果。

通訊模組核心程式系統架構

通訊模組核心程式提供了對訊息物件的讀取、設定、編譯與解譯的動作,同時也提 供控制器與控制器之間 TCP/IP 連線建立以及訊息的傳送與接收功能。為了遵照 SECS-II 標準,每個訊息必須加上 HSMS 所定義的 Header 並串接 SECS-II 所定義的訊息格式後 以位元組的方式傳送。當接受到訊息時,通訊模組將所收到的位元組解譯成相對應的訊 息物件,並將訊息物件放入 MessageQueue 物件中,提供控制器讀取通訊模組所接收 到的訊息物件。

(from Logical View)

Message RM (from Logical View)

SECS

-$theSECS

MessageQueue -MessageQ[]

圖 4.11 SECS 通訊模組類別圖

表 4.5 通訊模組參與物件說明表

Server 實作 Server Thread,當控制器為 Passive Mode 時建立 Socket 後即交給 PassiveEntity 物件等待 Active 端的連線。

StateMachine 遵照 HSMS 定義,紀錄每個連線 Socket 的狀態及實作逾時(Timeout)機制。

MessageHandle 將所接收的訊息 Header 解譯並產生對應的訊息物件。

MessageQueue 用來貯存已解譯完成的訊息物件,並提供方法給使用者讀取所貯存的訊息 物件。

Message 抽象類別,為所有訊息物件的父類別,提供所有訊息物件共通的屬性與方 法。

S4F27 為 SECS-II 所規範的訊息,以一個物件代表一個訊息,內含對其 Data Item 設定與讀取的方法。

GenerateSystemBytes HSMS 定義每個訊息的 Header 須有 SystemBytes 部份,且得是唯一,不 可重複,因此,此類別為 Singleton 物件,專司 SystemBytes 的產生。

4.4.2 訊息編譯循序圖

圖 4.12 說明了訊息物件 S4F19 的編譯流程與相關物件之間的互動。當使用者建 立好一個訊息物件後,呼叫 SECS 物件的 SendMessage()方法將其傳送出去時,其訊 息編譯步驟為:

1. SECS 物件呼叫訊息物件 S4F19 的 Encoder()。

2. 將每個 Data Item 依照 SECS-II 所規範的訊息架構,利用 ListItem 物件的 add() 方法將各個資料型態物件加入 ListItem 物件中。

3. 最上層的 ListItem 物件建立完成後,利用 EncoderVisitor 物件將 S4F19 訊息物 件編譯為文字字串。

4. 執行最上層的 ListItem 物件的 accept(),而此方法接著會去呼叫 EncoderVisitor

物件的 Visitor(),在 Visitor()中,會去將 ListItem 物件中的各個資料型態物件取 出,並分別去執行其 accept(),各個資料型態物件的 accept()又會去呼叫對應 的 EncoderVisitor 物件的 Visitor(),利用這樣的結構,將所有的「處理」在 EncoderVisitor 物件的 Visitor()中去實現,而達到 Visitor Pattern 的目的。

5. 最後再執行 EncoderVisitor 物件的 getString(),將所編譯的文字字串取出列印 或傳送。

: SECS : S4F19

list_1 : ListItem

test1 : EncoderVisitor

: StringItem : u_IntegerItem Encoder( ) 入 MessageQueue 物件中的流程,其訊息解譯步驟為:

1. 將所接收到的位元組訊息傳入 MessageHandle 物件中的 Decoder()執行,分析 訊息 Header,找出對應的訊息類別,並建立此訊息物件。

2. 去掉位元組訊息的訊息 Header,將剩下的位元組訊息傳入所建立訊息物件的

Decoder()中,執行解譯的動作。

3. 此訊息物件的 Decoder()會建立一個 DecoderVisitor 物件,並將位元組訊息傳 入此物件的 start()中。

4. start()依照 SECS-II 所規範的 Data Item 格式去解譯,並利用 Format Code 產 生對應的資料型態物件。

5. 所產生的資料型態物件,利用 ListItem 物件的 add()將各個資料型態物件加入 ListItem 物件中,並透過執行資料型態物件的 accept()及 DecoderVisitor 物件 的 visitor()方法完成訊息物件的解譯工作。

6. 最後再將解譯出來得到的訊息物件放入 MessageQueue 中,等待控制器建立 執行緒來將訊息物件取出。

: HSMS

: SECS

: MessageHandle : Message

: DecoderVisitor

: ListItem

: BooleanItem

:

accept(secsii .Visi tor.Visitor)

vi sit(secsii .Item.ListItem)

BooleanItem ( )

getInstance( )

Inser_RQ(Object) Decoder(byte[], int)

accept(secsii.Vi sitor.Visitor)

圖 4.13 訊息解譯的循序圖

4.4.4 傳送訊息循序圖

圖 4.14 說明了使用者(Actor)如何建立一個訊息物件,並將其利用 SECS 物件傳送 出去,傳送訊息的步驟為:

1. Actor 先建立一個 S4F19 訊息物件,並執行 set_DATAID()、set_TRJOBNAME() 等方法,設定訊息的 Data Item 值。

2. 接著 Actor 執行 SECS 物件的 SendMessage()方法並傳入 S4F19 訊息物件。

3. SECS 物件會執行所傳入訊息物件的 Encoder2Byte(),將訊息物件編譯為位元 組訊息。

4. SECS 物件執行 HSMS 物件的 SendData(),將位元組透過 Socket 傳送出去。

: CTC

: S4F19

: SECS : HSMS

SendMessage(String, secsii.Message) S4F19( )

set_DATAID(String)

set_TRJOBNAME(String) set_TRPORT(int)

SendDataMessage(boolean, int, int, byte[])

SendData(byte[

Encoder2Byte( )

圖 4.14 傳送訊息循序圖

4.4.5 接收訊息活動圖

圖 4.15 說明訊息接收的活動圖,所有經 Socket 傳送而接收的訊息,都會被解譯 為訊息物件並存放在 MessageQueue 物件中,使用者(Actor)對於所接收到的訊息,只 需要從 MessageQueue 物件中將訊息物件取出,其訊息接收的步驟為:

1. 建立一執行緒反覆檢查 MessageQueue 物件中是否有訊息物件。

2. 若無訊息物件,則繼續檢查;若有訊息物件,則將第一個訊息物件取出,並將 其從 MessageQueue 物件中刪除。

3. 判斷所取出訊息物件的 Stream ID 及 Function ID,決定此訊息物件為何,使用 者(Actor)才能對此訊息物件做處理。

4. 訊息處理完後,再次檢查 MessageQueue 物件中是否有訊息物件。

check the MessageQueue state

Empty Not Empty

get out message from MeesageQueue

remove the message from MessageQueue check the message

StreamID

check the message FunctionID

do the action which you want to do

圖 4.15 接收訊息活動圖