2.2消息發送方IMessageSender
從上面我們可以看出,消息發送方主要包含這樣幾個功能:登錄、連接、發送消息、注銷。另外在連接成功或失敗時還要通知用戶界面,發 送消息成功或失敗時也需要通知用戶界面,因此,我們可以讓連接和發送消息返回一個布爾類型的值,當它為真時表示連接或發送成功,反之 則為失敗。因為登錄沒有任何的業務邏輯,僅僅是記錄控件的值並進行顯示,所以我不打算將它寫到接口中。因此我們可以得出它的接口大致 如下:
public interface IMessageSender {
bool Connect(IPAddress ip, int port); // 連接到服務端
bool SendMessage(Message msg); // 發送用戶
void SignOut(); // 注銷系統
}
2.3消息接收方IMessageReceiver
而對於消息接收方,從上面我們可以看出,它的操作全是被動的:客戶端連接時自動提示,客戶端連接丟失時顯示自動提示,偵聽到消息時 自動提示。注意到上面三個詞都用了“自動”來修飾,在C#中,可以定義委托和事件,用於當程序中某種情況發生時,通知另外一 個對象。在這裡,程序即是我們的IMessageReceiver,某種情況就是上面的三種情況,而另外一個對象則為我們的用戶界面。因此,我們現在 首先需要定義三個委托:
public delegate void MessageReceivedEventHandler(string msg);
public delegate void ClIEntConnectedEventHandler(IPEndPoint endPoint);
public delegate void ConnectionLostEventHandler(string info);
接下來,我們注意到接收方需要偵聽消息,因此我們需要在接口中定義的方法是StartListen()和StopListen()方法,這兩個方法是典型的 技術相關,而不是業務相關,所以從用例中是看不出來的,可能大家現在對這兩個方法是做什麼的還不清楚,沒有關系,我們現在並不寫實現 ,而定義接口並不需要什麼成本,我們寫下IMessageReceiver的接口定義:
public interface IMessageReceiver {
event MessageReceivedEventHandler MessageReceived; // 接收到發來的消息
event ConnectionLostEventHandler ClIEntLost; // 遠程主動斷開連接
event ClientConnectedEventHandler ClIEntConnected; // 遠程連接到了本地
void StartListen(); // 開始偵聽端口
void StopListen(); // 停止偵聽端口
}
我記得曾經看過有篇文章說過,最好不要在接口中定義事件,但是我忘了他的理由了,所以本文還是將事件定義在了接口中。
2.4主程序Talker
而我們的主程序是既可以發送,又可以接收,一般來說,如果一個類像獲得其他類的能力,以采用兩種方法:繼承和復合。因為C#中沒有多 重繼承,所以我們無法同時繼承實現了IMessageReceiver和IMessageSender的類。那麼我們可以采用復合,將它們作為類成員包含在Talker內 部:
public class Talker {
private IMessageReceiver receiver;
private IMessageSender sender;
public Talker(IMessageReceiver receiver, IMessageSender sender) {
this.receiver = receiver;
this.sender = sender;
}
}
現在,我們的程序大體框架已經完成,接下來要關注的就是如何實現它,現在讓我們由設計走入實現,看看實現一個網絡聊天程序,我們需 要掌握的技術吧。
C#網絡編程基礎(篇外篇)
這部分的內容請參考 C#網絡編程 系列文章,共5個部分較為詳細的講述了基於Socket的網絡編程的初步內容。