Exemplo n.º 1
0
        /// <summary> 
        /// UDP打洞过程 
        /// 假设A想连接B.首先A发送打洞消息给Server,让Server告诉B有人想与你建立通话通道,Server将A的IP信息转发给B 
        /// B收到命令后向A发一个UDP包,此时B的NAT会建立一个与A通讯的Session. 然后A再次向B发送UDP包B就能收到了 
        /// </summary> 
        public void HolePunching(User user)
        {
            //A:自己; B:参数user
            //A发送打洞消息给服务器,请求与B打洞
            C2S_HolePunchingRequestMessage msg = new C2S_HolePunchingRequestMessage(_LocalUserName, user.UserName);
            SendMessage(msg, _hostPoint);

            Thread.Sleep(2000);//等待对方发送UDP包并建立Session

            //再向对方发送确认消息,如果对方收到会发送一个P2P_HolePunchingResponse确认消息,此时打洞成功
            P2P_HolePunchingTestMessage confirmMessage = new P2P_HolePunchingTestMessage(_LocalUserName);
            SendMessage(confirmMessage, user);
        }
Exemplo n.º 2
0
 public void SendMessage(MessageBase msg, User user)
 {
     SendMessage(msg, user.NetPoint);
 }
Exemplo n.º 3
0
        //线程主方法
        private void Run()
        {
            byte[] msgBuffer;

             while (true)
             {
            msgBuffer = _server.Receive(ref _remotePoint); //接受消息
            try
            {
               //将消息转换为对象
               object msgObject = ObjectSerializer.Deserialize(msgBuffer);
               if (msgObject == null) continue;

               Type msgType = msgObject.GetType();
               DoWriteLog("接收到消息:" + msgType);
               DoWriteLog("From:" + _remotePoint);

               //新用户登录
               if (msgType == typeof(C2S_LoginMessage))
               {
                  var lginMsg = (C2S_LoginMessage)msgObject;
                  DoWriteLog(string.Format("用户’{0}’已登录!", lginMsg.FromUserName));

                  // 添加用户到列表
                  var userEndPoint = new IPEndPoint(_remotePoint.Address, _remotePoint.Port);
                  var user = new User(lginMsg.FromUserName, userEndPoint);
                  _userList.Add(user);

                  DoUserChanged(_userList);

                  //通知所有人,有新用户登录
                  var msgNewUser = new S2C_UserAction(user, UserAction.Login);
                  foreach (User u in _userList)
                  {
                     if (u.UserName == user.UserName) //如果是自己,发送所有在线用户列表
                     SendMessage(new S2C_UserListMessage(_userList), u.NetPoint);
                     else
                     SendMessage(msgNewUser, u.NetPoint);
                  }
               }
               else if (msgType == typeof(C2S_LogoutMessage))
               {
                  var lgoutMsg = (C2S_LogoutMessage)msgObject;
                  DoWriteLog(string.Format("用户’{0}’已登出!", lgoutMsg.FromUserName));

                  // 从列表中删除用户
                  User logoutUser = _userList.Find(lgoutMsg.FromUserName);
                  if (logoutUser != null) _userList.Remove(logoutUser);

                  DoUserChanged(_userList);

                  //通知所有人,有用户登出
                  var msgNewUser = new S2C_UserAction(logoutUser, UserAction.Logout);
                  foreach (User u in _userList)
                  SendMessage(msgNewUser, u.NetPoint);
               }

               else if (msgType == typeof(C2S_HolePunchingRequestMessage))
               {
                  //接收到A给B打洞的消息,打洞请求,由客户端发送给服务器端
                  var msgHoleReq = (C2S_HolePunchingRequestMessage)msgObject;

                  User userA = _userList.Find(msgHoleReq.FromUserName);
                  User userB = _userList.Find(msgHoleReq.ToUserName);

                  // 发送打洞(Punching Hole)消息
                  DoWriteLog(string.Format("用户:[{0} IP:{1}]想与[{2} IP:{3}]建立对话通道.",
                  userA.UserName, userA.NetPoint,
                  userB.UserName, userB.NetPoint));

                  //由Server发送消息给B,将A的IP的IP地址信息告诉B,然后由B发送一个测试消息给A.
                  var msgHolePunching = new S2C_HolePunchingMessage(_remotePoint);
                  SendMessage(msgHolePunching, userB.NetPoint); //Server->B
               }
               else if (msgType == typeof(C2S_GetUsersMessage))
               {
                  // 发送当前用户信息
                  var srvResMsg = new S2C_UserListMessage(_userList);
                  SendMessage(srvResMsg, _remotePoint);
               }
            }
            catch (Exception ex) { DoWriteLog(ex.Message); }
             }
        }
Exemplo n.º 4
0
 public void Remove(User user)
 {
     InnerList.Remove(user);
 }
Exemplo n.º 5
0
 public void Add(User user)
 {
     InnerList.Add(user);
 }
Exemplo n.º 6
0
 public S2C_UserAction(User user, UserAction action)
 {
     _User = user;
     _Action = action;
 }