示例#1
0
        //进入聊天室
        public string[] Join(string name)
        {
            bool userAdded = false;

            //由于服务端一次可以处理多个实例,所以需要锁定以便保证数据的一致性
            lock (syncObj)
            {
                //如果请求的昵称在成员字典中不存在并且昵称不空
                if (!chatters.ContainsKey(name) && name != "" && name != null)
                {
                    //全局昵称记录
                    this.name = name;
                    //保存昵称和ChatEventHandler的代理,这个代理只是一个指向而已
                    //如果想调用的话,可以通过同步调用:ChatEventHandler(object sender,ChatEventArgs e )
                    //也可以通过异步调用:ChatEventHandler.BeginInvoke(***)的方式来,本实例采用后一种。
                    chatters.Add(name, MyEventHandler);
                    userAdded = true;
                }
            }

            if (userAdded)
            {
                //获取当前操作客户端实例的通道给IChatCallback接口的实例callback,
                //此通道是一个定义为IChatCallback类型的泛类型
                //通道的类型是事先服务契约协定好的双工机制(见IChat前的ServiceContract)
                callback = OperationContext.Current.GetCallbackChannel <IChatCallback>();
                //实例化事件消息类并赋值
                ChatEventArgs e = new ChatEventArgs();
                e.msgType = MessageType.UserEnter;
                e.name    = name;

                //其实这里就是抛出事件,只不过利用了异步的方式来将事件抛出,同步抛出方式为:handler(this,e)
                //事件抛出后,需要接收方,下面一句就是将这个抛出的事件给接收住了。所以如果下面一条代码放到上面来,
                //就会收到自己进到聊天室的信息。
                BroadcastMessage(e);

                //这里也是处理回调信息的地方。将用户的加入信息回调出去发送给客户端。
                //这里也是注册事件的地方,将刚刚抛出的事件接收住,去处理。也就是当用户进入后,发送回调信息给客户端,告知用户已经进入。
                ChatEvent += MyEventHandler;
                //以下代码返回当前进入聊天室成员的称列表
                string[] list = new string[chatters.Count];
                lock (syncObj)
                {
                    //从成员字典索引0 开始复制chatters成员字典的key 值到list 字符串数组
                    chatters.Keys.CopyTo(list, 0);
                }
                return(list);
            }
            else
            {
                //当昵称重复或为空是,如果客户端做了为空检测,则可直接认为是名称重复,当前要在没有异常的情况下。
                return(null);
            }
        }
示例#2
0
        //发送广播信息
        //要点:根据上下文理解: 1 广播什么(what),2 为谁广播(who),3“谁”从哪来(where),4 如何来的(how)
        private void BroadcastMessage(ChatEventArgs e)
        {
            //创建回调委托事件实例ChatEvent的一个副本,之所以用副本是因为ChatEvent处于多线程并状态(?此处不知理解是否正确,因为我理解后面的handler 是一个引用,自相矛盾了)
            ChatEventHandler temp = ChatEvent;

            if (temp != null)
            {
                //GetInvocationList方法,按照调用顺序返回“多路广播委托(MulticastDelegate)”的调用列表
                foreach (ChatEventHandler handler in temp.GetInvocationList())
                {
                    //异步方式调用多路广播委托的调用列表中的ChatEventHandler
                    //BeginInvoke方法异步调用,即不等等执行,详细说明则是:公共语言运行库(CLR) 将对请求进行排队并立即返回到调用方。将对来自线程池的线程调用该目标方法。
                    //EndAsync 为线程异步调用完成的回调方法,EndAsync 接收并操持着线程异步调用的操作状态,可通过此结果找到调用者,如此例handler,handler是一个委托实例的引用
                    //        此状态为调用者(委托)的事件声明类型此例为public event ChatEventHandler ChatEvent; 中的ChatEventHandler
                    //最后一个参数:包含的对象的状态信息,传递给委托;
                    handler.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
                }
            }
        }
示例#3
0
        //成员离开聊天室
        public void Leave()
        {
            if (this.name == null)
            {
                return;
            }

            //删除成员字典中的当前会话的成员,及删除多路广播委托的调用列表中的当前调用
            //name 和myEventHandler 的生存周期是在当前会话中一直存在的,参考Session 周期
            lock (syncObj)
            {
                chatters.Remove(this.name);
            }
            ChatEvent -= MyEventHandler;
            ChatEventArgs e = new ChatEventArgs();

            e.msgType = MessageType.UserLeave;
            e.name    = this.name;
            this.name = null;
            BroadcastMessage(e);
        }
示例#4
0
        //单聊
        public void Whisper(string to, string msg)
        {
            ChatEventArgs e = new ChatEventArgs();

            e.msgType = MessageType.ReceiveWhisper;
            e.name    = this.name;
            e.message = msg;
            try
            {
                //创建一个临时委托实例
                ChatEventHandler chatterTo;
                lock (syncObj)
                {
                    //查找成员字典中,找到要接收者的委托调用
                    chatterTo = chatters[to];
                }
                //异步调用,由于这个委托对象是唯一的,所以直接调用即可。当然也ChatEvent += MyEventHandler;注册注册
                chatterTo.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
            }
            catch (KeyNotFoundException)
            {
                //访问集合中元素的键与集合中的任何键都不匹配时所引发的异常
            }
        }
 /// <summary>
 /// �̺�Ʈ �߻�
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void MyEventHandler(object sender, ChatEventArgs e)
 {
     try
       {
     //Ŭ���̾�Ʈ���� ������
     switch (e.msgType)
     {
       case MessageType.Receive:
     callback.Receive(e.name, e.message);
     break;
       case MessageType.ReceiveWhisper:
     callback.ReceiveWhisper(e.name, e.message);
     break;
       case MessageType.UserEnter:
     callback.UserEnter(e.name);
     break;
       case MessageType.UserLeave:
     callback.UserLeave(e.name);
     break;
     }
       }
       catch//������ �߻����� ���
       {
     Leave();
       }
 }
        /// <summary>
        /// ��ü Ŭ���̾�Ʈ�鿡�� �̺�Ʈ�� �����Ѵ�.
        /// </summary>
        /// <param name="e"></param>
        private void BroadcastMessage(ChatEventArgs e)
        {
            //�̺�Ʈ
              ChatEventHandler temp = ChatEvent;

              if (temp != null)
              {
            //���� �̺�Ʈ���� �����Ѵ�.
            foreach (ChatEventHandler handler in temp.GetInvocationList())
            {
              handler.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
            }
              }
        }
 public void Whisper(string to, string msg)
 {
     ChatEventArgs e = new ChatEventArgs();
       e.msgType = MessageType.ReceiveWhisper;
       e.name = this.name;
       e.message = msg;
       try
       {
     ChatEventHandler chatterTo;
     lock (syncObj)
     {
       chatterTo = chatters[to];
     }
     chatterTo.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
       }
       catch (KeyNotFoundException)
       {
       }
 }
 public void Say(string msg)
 {
     ChatEventArgs e = new ChatEventArgs();
       e.msgType = MessageType.Receive;
       e.name = this.name;
       e.message = msg;
       BroadcastMessage(e);
 }
        public void Leave()
        {
            if (this.name == null) return;

              lock (syncObj)
              {
            chatters.Remove(this.name);
              }
              ChatEvent -= myEventHandler;

              //���ο� �̺�Ʈ �߻�
              ChatEventArgs e = new ChatEventArgs();
              e.msgType = MessageType.UserLeave;
              e.name = this.name;
              BroadcastMessage(e);
        }
        /// <summary>
        /// * JOIN �޼��� 
        /// Ư���� ����ڰ� �濡 ó�� ��� ������ ������� �̸��� �޾Ƽ� 
        /// ó���Ѵ�.
        /// </summary>
        /// <param name="name">����� �̸�</param>
        /// <returns>���� �̸��� ���� ��쿡�� ����� ����Ʈ�� ��ȯ�Ѵ�</returns>
        public string[] Join(string name)
        {
            myEventHandler = new ChatEventHandler(MyEventHandler);

              lock (syncObj)
              {
            if (!chatters.ContainsKey(name))//�̸��� ���� ä�Ϳ� �ִ��� �˻��Ѵ�.
            {
              //�̸��� �̺�Ʈ�� �߰��Ѵ�.
              this.name = name;
              chatters.Add(name, MyEventHandler);

              //����ڿ��� ���� �� ä���� �����Ѵ�.
              callback = OperationContext.Current.GetCallbackChannel<IChatCallback>();

              //UserEnter ��� �̺�Ʈ�� �����Ѵ�
              ChatEventArgs e = new ChatEventArgs();
              e.msgType = MessageType.UserEnter;
              e.name = name;
              BroadcastMessage(e);

              //���������� �߰�
              ChatEvent += myEventHandler;

              //����ڸ���Ʈ�� �����ش�.
              string[] list = new string[chatters.Count];
              lock (syncObj)
              {
            chatters.Keys.CopyTo(list, 0);
              }
              return list;
            }
            else //�̹� ����ڰ� ����ϰ� �ִ� �̸��� ���
            {
              return null;
            }
              }
        }