C#仿QQ聊天程序v1.0(客户端管理类)
作者:C/S框架网  发布日期:2011/06/26 22:19:17
C#仿QQ聊天程序v1.0(客户端管理类)

[原创]C#仿QQ聊天程序v1.0(客户端管理类)

ChatClientLib类是本程序相当重要的一个类,包括监听消息,用户管理,发送消息及处理未读消息等功能。请结合其它类来认真学习这个程序。



/// <summary>
/// 聊天程序管理类
/// </summary>
public class ChatClientLib
{

        private IConnectionList _Connections = null; //联系人列表

        private ChatConnection _CurrentConnection = null; //当前联系人对象

        private IList _SendMsgProxyList = new ArrayList(); //与用户聊天打开的聊天窗口

        private ArrayList _NotifyList = new ArrayList();//收到未查看消息列表

        private TcpListener _ServerListener = null; //本地消息监听

        private Thread _ServerListenerThread = null; //监听使用的线程      

        private bool _ServerRunning = false;//运行服务器标志

 

        private IPAddress _LocalServerIP; //本地服务器地址

        private int _LocalServerPort = 5858;//本地服务器端口


//CSFramework原创作品,如转载请注明出处 by C/S框架网 www.csframework.com 

        private IMessageContainer _MessageHistory = new NullLog();

        public IMessageContainer MessageHistory { get { return _MessageHistory; } set { _MessageHistory = value; } }

 

        //构造器

        public ChatClientLib(IConnectionList Connections)

        {

            _LocalServerIP = Dns.GetHostAddresses(Dns.GetHostName())[0];

            _Connections = Connections;

            _CurrentConnection = new ChatConnection(Loginer.Current.AccountName, Loginer.Current.Account,
Loginer.Current.FactoryCode, _LocalServerIP.ToString(), _LocalServerPort, ChatState.Online);

        }

 

        //未读消息列表

        public ArrayList NotifyList { get { return _NotifyList; } }

 

        //在线用户列表

        public IConnectionList Connections { get { return _Connections; } set { _Connections = value; } }

 

        //当前用户连接(登录的用户)

        public ChatConnection CurrentConnection { get { return _CurrentConnection; } }

 

        private frmShowMessage _ShowMsgForm = new frmShowMessage();

        private void ShowMessage(string msg)

        {

            _ShowMsgForm.ShowMessage(msg);

            ChatCommon.ShowWindow(_ShowMsgForm.Handle, 1);

            ChatCommon.SetForegroundWindow(_ShowMsgForm.Handle);

        }


   
   //启动聊天服务器程序. 参数说明 ip:本地消息服务器IP地址; port:端口
   public void StartMessageServer(string localServerIp, int localServerPort)
   {
      if (_ServerRunning) return;
      
      _LocalServerIP = IPAddress.Parse(localServerIp);
      _LocalServerPort = localServerPort;
      
      //构建监听
      _ServerListener = new TcpListener(_LocalServerIP, _LocalServerPort);
      _ServerListener.Start(255);
      _ServerRunning = true;
      
      //启动线程
      _ServerListenerThread = new Thread(new ThreadStart(DoStartServerListener));
      _ServerListenerThread.IsBackground = true;
      _ServerListenerThread.Start();
      
      this.UpdateOnlineState(1);
      
   }
   
   //关闭聊天服务器程序.
   public void StopMessageServer()
   {
      _ServerRunning = false;
      _ServerListener.Stop();
      _ServerListenerThread.Abort("101");
      _ServerListenerThread = null;
      
      //登出,删除在线记录
      this.UpdateOnlineState(0);
   }
   
   /// <summary>
   ///启动聊天服务器程序.
   /// </summary>
   private void DoStartServerListener()
   {
      try
      {
         //监听客户连线请求
         while (_ServerRunning)
         {
            if (_ServerListener == null) return; //防止其它地方关闭监听
            
            Socket socket = _ServerListener.AcceptSocket(); //有客户请求连接
            if (socket == null) continue;
            
            byte[] buffer = new Byte[socket.ReceiveBufferSize];
            int i = socket.Receive(buffer); //接收请求数据.
            if (i <= 0) continue;
            
            //处理对象流
            if (ChatCommon.IsObjectStream(buffer))
            {
               _MessageHistory.AddMessage("接受到服务器发送的对象数据.");
               DoAnalyzeObject(buffer);
               socket.Close();
               continue;
            }
            socket.Close();
         }
      }
      catch (Exception ex)
      {
         if (ex is ThreadAbortException)
         {
            if ((ex as ThreadAbortException).ExceptionState.ToString() == "101")
            _ServerRunning = false;
         }
      }
   }
   
   /// <summary>
   /// 获取用户头像
   /// </summary>
   /// <param name="account"></param>
   /// <returns></returns>
   private System.Drawing.Image GetUserPhoto(string account)
   {
      return ChatCommon.GetImage("chat_woman.ico");
   }
   
   /// <summary>
   /// 发送消息
   /// </summary>
   public void SendToClient(ChatConnection conn, cmdBase message)
   {
      TcpClient client = new TcpClient();
      ChatCommon.TryConnect(client, conn.IP, conn.Port);
      byte[] data = ChatCommon.GetObjectArray(message);
      if (client.Connected) client.Client.Send(data);
      client.Close();
   }
   
   /// <summary>
   /// 分析接受到的数据(字节数组)
   /// </summary>
   /// <param name="buffer"></param>
   private void DoAnalyzeObject(byte[] buffer)
   {
      object o = ChatCommon.GetObject(buffer);
      
      if (o is cmdMessage)//普通消息
      {
         cmdMessage msg = o as cmdMessage;
         
         _MessageHistory.AddMessage(msg.Sender + "说:" + msg.Content);
         
         //当收到消息,如果有打开与发送者聊天的窗口,则显示消息.否则闪烁图标.
         ISendMsgProxy proxy = GetSendMsgProxy(msg.Sender);
         if (proxy == null)
         {
            _Connections.AddReceivedMessage(msg.Sender, msg.Content);
            _Connections.FlashConnection(msg.Sender);
            _NotifyList.Add(new NotifyItem(NotifyType.Message, msg.Sender));
         }
         else
         {
            proxy.ShowMessage(ShowMessageType.ShowTargetMessage, msg.Content);
         }
      }
      else if (o is cmdNotifyOnline) //好友通知上线
      {
         cmdNotifyOnline msg = o as cmdNotifyOnline;
         ChatConnection conn = new ChatConnection(msg.NickName, msg.Sender, msg.FactoryCode, msg.IP,
msg.Port, ChatState.Online);
         _Connections.AddConnection(conn);
      }
      else if (o is cmdExit) //好友通知上线
      {
         _Connections.RemoveConnection((o as cmdExit).Sender);
      }
   }
   
   //增加发送消息窗体
   public void AddSendMsgProxy(ISendMsgProxy proxy)
   {
      if (_SendMsgProxyList.IndexOf(proxy) < 0)
      _SendMsgProxyList.Add(proxy);
   }
   
   //获取发送消息窗体
   private ISendMsgProxy GetSendMsgProxy(string account)
   {
      for (int i = 0; i <= _SendMsgProxyList.Count - 1; i++)
      {
         ISendMsgProxy proxy = _SendMsgProxyList[i] as ISendMsgProxy;
         if (proxy.TargetConnection.Account == account) return proxy;
      }
      return null;
   }
   
   //增加一个用户连接
   private void AddClient(ChatConnection client)
   {
      //有相同的IP存在,不加载
      object o = _Connections.GetConnection(client.Account);
      if (o == null)
      _Connections.AddConnection(client);
   }
   
   //登出
   public void Logout()
   {
      IList list = _Connections.GetConnections();
      cmdExit msg = new cmdExit(_CurrentConnection.Account);
      //通知所有好友
      foreach (ChatConnection conn in list)
      {
         if (conn == _CurrentConnection) continue;
         if (conn.ConnectionState == ChatState.Online)
         SendToClient(conn, msg);
      }
      
      _Connections.CloseAll(false);//关闭所有连接
      
      if (_MessageHistory != null) _MessageHistory.AddMessage("登出成功!");
   }
   
   //发送消息给所有用户
   public void SendToAllClient(cmdBase message)
   {
      IList list = _Connections.GetConnections();
      foreach (ChatConnection conn in list)
      {
         if (conn.Account == Loginer.Current.Account) continue;
         if (conn.ConnectionState != ChatState.Online) continue;
         
         SendToClient(conn, message);
      }
   }
   
   //显示发送消息窗体
   public void ShowSendMsgForm(ChatConnection conn)
   {
      ISendMsgProxy proxy = GetSendMsgProxy(conn.Account);
      if (proxy == null)
      {
         proxy = frmSendMessage.Execute(this, this.CurrentConnection, conn);
         AddSendMsgProxy(proxy);
      }
      
      //有未读消息
      if (conn.ReceivedMessage.Count > 0)
      {
         proxy.ShowMessage(ShowMessageType.ShowTargetMessage, conn.ReceivedMessage);
         conn.ReceivedMessage.Clear();
         _Connections.StopFlash(conn.Account);
      }
      
      proxy.ShowMe();
   }
   
   //处理系统通知.优先处理最后一个消息.处理完毕删除通知.
   public void ProcessNotify()
   {
      NotifyItem item = _NotifyList[_NotifyList.Count - 1] as NotifyItem;//先处理最后的消息
      
      if (item.NotifyType == NotifyType.Information)
      {
         ShowMessage(item.Content.ToString());
      }
      else if (item.NotifyType == NotifyType.Message)
      {
         string account = item.Content.ToString();
         ChatConnection conn = _Connections.GetConnection(account);
         if (conn != null) ShowSendMsgForm(conn);
      }
      _NotifyList.RemoveAt(_NotifyList.Count - 1); //删除最后一个通知
   }
   
   //删除发送消息窗体
   public void RemoveSendMsgProxy(ISendMsgProxy frmSendMessage)
   {
      _SendMsgProxyList.Remove(frmSendMessage);
   }
   
   //显示连接消息
   public void ShowConnection(ChatConnection conn)
   {
      frmConnectionInfo.ShowConnection(conn);
   }
   
   //加载用户列表
   public void LoadUserList(ShowUser type)
   {
      DataTable dt = ChatDAL.GetOnlineUsers();
      IList list = new ArrayList();
      _Connections.CloseAll();
      _Connections.ShowUserType = type;
      
      foreach (DataRow row in dt.Rows)
      {
         ChatConnection conn = CreateChatConnection(row);
         
         //当前处理的连接对象是自己,放第一行显示
         if (row["Account"].ToString() == Loginer.Current.Account)
         _Connections.AddConnection(0, conn);
         else
         _Connections.AddConnection(conn);
      }
   }
   
   //DataRow转换为ChatConnection对象
   private ChatConnection CreateChatConnection(DataRow row)
   {
      ChatConnection conn = new ChatConnection();
      conn.Account = row["Account"].ToString();
      conn.ConnectionState = ChatState.Online;
      conn.DisplayName = row["AccountName"].ToString();
      conn.IP = row["NativeIP"].ToString();
      conn.Port = int.Parse(row["NativePort"].ToString());
      conn.FactoryCode = row["FactoryCode"].ToString();
      return conn;
   }
   
   //更新用户状态.
   public void UpdateOnlineState(int state)
   {
      //保存用户在线记录
      ChatDAL.UpdateOnlineState(Loginer.Current.Account, _LocalServerIP.ToString(), _LocalServerPort, state);
   }
   
}

//CSFramework原创作品,如转载请注明出处 by C/S框架网 www.csframework.com 


上一篇 下一篇