[wcf]入門.4.2

本篇完成 4.1 所述聊天系統基本功能部分
 
先看下使用截圖
 
 
通過菜單中的 file ,load 登錄,需輸入名字
主界面左側爲當前在線角色列表
右側上方爲當前所有聊天信息集
右側下方爲聊天信息輸入窗口(暫且掛鉤廣播聊天)
 
 
工程結構描述
 
ChatProtocal 聊天協議
ChatService  服務實現
ChatHost 服務宿主(console 程序)
ChatClient 客戶端(winform 程序)
 
 
涉及到的類型
 
IChatService 服務契約
IChatServiceCallback 服務回調契約
User 角色信息體
ChatService 服務實現
UserManager 用戶管理
ChaterForm 回調協議實現
 
 
關鍵代碼段
聊天協議,需會話狀態存儲用戶信息,開啓重入防止死鎖

        [ServiceContract(Namespace = "szgamer",
                Name = "ChatService",    
                SessionMode = SessionMode.Required,    
                ProtectionLevel = ProtectionLevel.None,
                CallbackContract=typeof(IChatServiceCallback))]
        public interface IChatService
        {
                [OperationContract(Name="Enter",IsOneWay=true)]
                void Enter(string name);
                [OperationContract(Name = "Exit", IsOneWay = true)]
                void Exit();
                [OperationContract(Name = "BroadcastChat", IsOneWay = true)]
                void BroadcastChat(string content);
                [OperationContract(Name = "PrivateChat", IsOneWay = true)]
                void PrivateChat(string target, string content);
        }

聊天回調協議

        public interface IChatServiceCallback
        {
                [OperationContract(Name = "BroadcastChated", IsOneWay = true)]
                void BroadcastChated(User who, string content);
                [OperationContract(Name = "PrivateChated", IsOneWay = true)]
                void PrivateChated(User who, string content);
                [OperationContract(Name = "NotifyUserList", IsOneWay = true)]
                void NotifyUserList(IList<User> users);
        }

用戶信息體,只公開運行時標識和名字給客戶端

        [DataContract(Namespace = "szgamer", Name = "User")]
        public class User : IExtensibleDataObject
        {
                [DataMember(Name = "Rtid", IsRequired = true, Order = 0)]
                public string Rtid
                {
                        get;
                        set;
                }
                [DataMember(Name = "Name", IsRequired = true, Order = 1)]
                public string Name
                {
                        get;
                        set;
                }

                public ExtensionDataObject ExtensionData
                {
                        get;
                        set;
                }

                public IChatServiceCallback Callback
                {
                        get;
                        set;
                }

                public User(string rtid, string name, IChatServiceCallback callback)
                {
                        Rtid = rtid;
                        Name = name;
                        Callback = callback;
                }

                public override string ToString()
                {
                        return string.Format("{0}: {1}", Name, Rtid);
                }
        }

 
用戶管理部分,使用需考慮線程安全

        public class UserManager
        {
                List<User> _UserList = new List<User>();

                public IList<User> UserList
                {
                        get { return _UserList; }
                }

                object _SyncRoot = new object();
                public object SyncRoot
                {
                        get { return _SyncRoot; }
                }

                public event Action UserListChanged;

                void RaiseUserListChanged()
                {
                        var h = UserListChanged;
                        if (h != null)
                        {
                                h();
                        }
                }

                public void AddUser(User user)
                {
                        _UserList.Add(user);

                        RaiseUserListChanged();
                }

                public void Remove(string user)
                {
                        foreach (var i in _UserList)
                        {
                                if (i.Rtid == user)
                                {
                                        _UserList.Remove(i);
                                        RaiseUserListChanged();
                                        return;
                                }
                        }
                }

                public bool Contains(string user)
                {
                        return GetUser(user) != null;
                }

                public User GetUser(string user)
                {
                        foreach (var i in _UserList)
                        {
                                if (i.Rtid == user)
                                {
                                        return i;
                                }
                        }

                        return null;
                }
        }


聊天信息廣播

                public void BroadcastChat(string content)
                {
                        lock (_UserManager.SyncRoot)
                        {
                                var user = _UserManager.GetUser(SessionId);
                                if (user == null)
                                        return;
                                Console.WriteLine(string.Format("[BroadcastChat] {`0`} {1}", user.ToString(), content));

                                foreach (var i in _UserManager.UserList)
                                {
                                        i.Callback.BroadcastChated(user, content);
                                }
                        }
                }


tcp 綁定,忽略安全

                <bindings>
                        <netTcpBinding>
                                <binding name="tcpBinding">
                                        <security mode="None">
                                        </security>
                                </binding>
                        </netTcpBinding>
                </bindings>

 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章