分享一个C#编写简单的聊天程序(详细介绍)

2019-12-26 16:55:38刘景俊

2.1消息Message

首先我们可以定义消息,前面我们已经明确了消息包含三个部分:用户名、时间、内容,所以我们可以定义一个结构来表示这个消息:


public struct Message {
 private readonly string userName;
 private readonly string content;
 private readonly DateTime postDate;

 public Message(string userName, string content) {
  this.userName = userName;
  this.content = content;
  this.postDate = DateTime.Now;
 }

 public Message(string content) : this("System", content) { }

 public string UserName {
  get { return userName; }
 }

 public string Content {
  get { return content; }
 }

 public DateTime PostDate {
  get { return postDate; }
 }

 public override string ToString() {
  return String.Format("{0}[{1}]:rn{2}rn", userName, postDate, content);
 }
 }

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的接口定义: