Esempio n. 1
0
            private void ProcessRosterIQ(IQ iq)
            {
                bool bSend = false;
                if (iq.Type == IqType.get)
                {
                    // Send the roster
                    // we send a dummy roster here, you should retrieve it from a
                    // database or some kind of directory (LDAP, AD etc...)

                    RosterIq rosterIq = new RosterIq(IqType.result);
                    rosterIq.Namespace = agsXMPP.Uri.CLIENT;
                    rosterIq.Id = iq.Id;
                    rosterIq.From = iq.To;
                    rosterIq.To = this.m_ClientAccount.JID;

                    foreach (Friend friend in this.m_ClientAccount.Friends)
                    {
                        RosterItem ri = new RosterItem();
                        ri.Name = friend.Nick;
                        ri.Subscription = friend.SubscriptionType;

                        ////............
                        //friend.JID.Resource = friend.Resource[0];

                        ri.Jid = friend.JID;
                        foreach (string strGroup in friend.Groups)
                        {
                            ri.AddGroup(strGroup);
                        }

                        rosterIq.Query.AddRosterItem(ri);
                    }

                    Send(rosterIq);

                }
                else if (iq.Type == IqType.set)
                {
                    //Received: 
                    //<iq xmlns="jabber:client" id="agsXMPP_18" type="set">
                    //    <query xmlns="jabber:iq:roster">
                    //        <item jid="test2@localhost"/>
                    //    </query>
                    //</iq>

                    //Send: 
                    //<iq xmlns="jabber:client" type="set" id="712">
                    //    <query xmlns="jabber:iq:roster">
                    //        <item name="test2" jid="test2@localhost" subscription="none"/>
                    //    </query>
                    //</iq>

                    //Send: 
                    //<iq xmlns="jabber:client" from="test@localhost/MF" to="test@localhost/MF" type="result" id="agsXMPP_18" />

                    Roster oldRoster = iq.Query as Roster;

                    RosterItem[] rosterItems = oldRoster.GetRoster();

                    Friend friend = null;

                    foreach (RosterItem rosterItem in rosterItems)
                    {
                        if (rosterItem.HasAttribute("subscription"))
                        {
                            if (rosterItem.Subscription == SubscriptionType.remove)
                            {
                                friend = this.m_ClientAccount.FindFriend(rosterItem.Jid.ToString());
                                if (friend == null)
                                {
                                    IQ error = new IQ(IqType.error);
                                    error.Namespace = iq.Namespace;
                                    error.Id = iq.Id;
                                    error.To = this.m_ClientAccount.JID;

                                    Send(error);
                                }

                                this.m_ClientAccount.RemoveFriend(friend);


                                RosterIq newRosterIq = null;
                                RosterItem ri = null;

                                Presence newPresence = null;

                                Account contactAccount = this.m_Server.AccountManager.FindAccount(rosterItem.Jid.ToString());
                                Friend userFriend = contactAccount.FindFriend(this.m_ClientAccount.JID.ToString());
                                if (userFriend == null)
                                {

                                    //RECV: 
                                    //<iq xmlns="jabber:client" id="agsXMPP_17" type="set">
                                    //    <query xmlns="jabber:iq:roster">
                                    //        <item jid="test@localhost" subscription="remove" />
                                    //    </query>
                                    //</iq>

                                    //SEND: <iq type="result" id="agsXMPP_17" to="test2@localhost/MF" from="test2@localhost/MF" />

                                    IQ result = new IQ(IqType.result);
                                    result.Id = iq.Id;
                                    result.From = this.m_ClientAccount.JID;
                                    result.To = this.m_ClientAccount.JID;
                                    Send(result);


                                    //SEND: 
                                    //<iq id="221" type="set">
                                    //    <query xmlns="jabber:iq:roster">
                                    //        <item jid="test@localhost" subscription="remove" />
                                    //    </query>
                                    //</iq>

                                    newRosterIq = new RosterIq(IqType.set);
                                    newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                                    ri = new RosterItem();
                                    ri.Name = rosterItem.Name;
                                    ri.Jid = rosterItem.Jid;
                                    ri.Subscription = rosterItem.Subscription;

                                    newRosterIq.Query.AddRosterItem(ri);

                                    Send(newRosterIq);


                                    //SEND: <presence from="test2@localhost/MF" xml:lang="zh-cn" type="unavailable" to="test@localhost/MF" />
                                    newPresence = new Presence();
                                    newPresence.From = this.m_ClientAccount.JID;
                                    newPresence.To = rosterItem.Jid;
                                    newPresence.Type = PresenceType.unavailable;
                                    newPresence.Language = this.objClientlanguage.Name;

                                    bSend = Send(newPresence.To, newPresence);
                                    if (!bSend)
                                    {

                                    }

                                }
                                else
                                {
                                    if (userFriend.SubscriptionType == SubscriptionType.both)
                                    {

                                        userFriend.SubscriptionType = SubscriptionType.to;
                                        userFriend.Save();

                                        newRosterIq = new RosterIq(IqType.set);
                                        newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                                        ri = new RosterItem();
                                        ri.Name = userFriend.Nick;
                                        ri.Jid = userFriend.JID;
                                        ri.Subscription = userFriend.SubscriptionType;

                                        newRosterIq.Query.AddRosterItem(ri);

                                        bSend = Send(rosterItem.Jid, newRosterIq);
                                        if (!bSend)
                                        {

                                        }

                                        newPresence = new Presence();
                                        newPresence.From = this.m_ClientAccount.JID;
                                        newPresence.To = rosterItem.Jid;

                                        newPresence.Type = PresenceType.unsubscribe;
                                        bSend = Send(rosterItem.Jid, newPresence);
                                        if (!bSend)
                                        {

                                        }

                                        userFriend.SubscriptionType = SubscriptionType.none;
                                        userFriend.Save();

                                        newRosterIq = new RosterIq(IqType.set);
                                        newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                                        ri = new RosterItem();
                                        ri.Name = userFriend.Nick;
                                        ri.Jid = userFriend.JID;
                                        ri.Subscription = userFriend.SubscriptionType;

                                        newRosterIq.Query.AddRosterItem(ri);

                                        bSend = Send(rosterItem.Jid, newRosterIq);
                                        if (!bSend)
                                        {

                                        }

                                        newPresence.Type = PresenceType.unsubscribed;
                                        bSend = Send(rosterItem.Jid, newPresence);
                                        if (!bSend)
                                        {

                                        }

                                        newPresence = new Presence();
                                        newPresence.From = rosterItem.Jid;
                                        newPresence.To = this.m_ClientAccount.JID;
                                        newPresence.Type = PresenceType.unavailable;
                                        newPresence.Language = this.objClientlanguage.Name;

                                        bSend = Send(newPresence.To, newPresence);
                                        if (!bSend)
                                        {

                                        }

                                        newPresence.SwitchDirection();
                                        bSend = Send(newPresence.To, newPresence);
                                        if (!bSend)
                                        {

                                        }

                                        IQ result = new IQ(IqType.result);
                                        result.Id = iq.Id;
                                        result.From = this.m_ClientAccount.JID;
                                        result.To = this.m_ClientAccount.JID;
                                        Send(result);


                                        newRosterIq = new RosterIq(IqType.set);
                                        newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                                        ri = new RosterItem();
                                        ri.Name = rosterItem.Name;
                                        ri.Jid = rosterItem.Jid;
                                        ri.Subscription = rosterItem.Subscription;

                                        newRosterIq.Query.AddRosterItem(ri);

                                        Send(newRosterIq);


                                    }
                                    else if (userFriend.SubscriptionType == SubscriptionType.from)
                                    {
                                        contactAccount.RemoveFriend(userFriend);
                                        contactAccount.Save();

                                        newPresence = new Presence();
                                        newPresence.From = this.m_ClientAccount.JID;
                                        newPresence.To = rosterItem.Jid;
                                        newPresence.Type = PresenceType.unavailable;
                                        newPresence.Language = this.objClientlanguage.Name;

                                        bSend = Send(newPresence.To, newPresence);
                                        if (!bSend)
                                        {

                                        }

                                        IQ result = new IQ(IqType.result);
                                        result.Id = iq.Id;
                                        result.From = this.m_ClientAccount.JID;
                                        result.To = this.m_ClientAccount.JID;
                                        Send(result);


                                        newRosterIq = new RosterIq(IqType.set);
                                        newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                                        ri = new RosterItem();
                                        ri.Name = rosterItem.Name;
                                        ri.Jid = rosterItem.Jid;
                                        ri.Subscription = rosterItem.Subscription;

                                        newRosterIq.Query.AddRosterItem(ri);

                                        Send(newRosterIq);

                                    }
                                    else if (userFriend.SubscriptionType == SubscriptionType.to)
                                    {
                                        userFriend.SubscriptionType = SubscriptionType.none;
                                        userFriend.Save();

                                        newRosterIq = new RosterIq(IqType.set);
                                        newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                                        ri = new RosterItem();
                                        ri.Name = userFriend.Nick;
                                        ri.Jid = userFriend.JID;
                                        ri.Subscription = userFriend.SubscriptionType;

                                        newRosterIq.Query.AddRosterItem(ri);

                                        bSend = Send(rosterItem.Jid, newRosterIq);
                                        if (!bSend)
                                        {

                                        }

                                        newPresence = new Presence();
                                        newPresence.From = this.m_ClientAccount.JID;
                                        newPresence.To = rosterItem.Jid;
                                        newPresence.Type = PresenceType.unsubscribed;
                                        bSend = Send(newPresence.To, newPresence);
                                        if (!bSend)
                                        {

                                        }

                                        newPresence = new Presence();
                                        newPresence.From = this.m_ClientAccount.JID;
                                        newPresence.To = rosterItem.Jid;
                                        newPresence.Type = PresenceType.unavailable;
                                        newPresence.Language = this.objClientlanguage.Name;

                                        bSend = Send(newPresence.To, newPresence);
                                        if (!bSend)
                                        {

                                        }

                                        IQ result = new IQ(IqType.result);
                                        result.Id = iq.Id;
                                        result.From = this.m_ClientAccount.JID;
                                        result.To = this.m_ClientAccount.JID;
                                        Send(result);


                                        newRosterIq = new RosterIq(IqType.set);
                                        newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                                        ri = new RosterItem();
                                        ri.Name = rosterItem.Name;
                                        ri.Jid = rosterItem.Jid;
                                        ri.Subscription = rosterItem.Subscription;

                                        newRosterIq.Query.AddRosterItem(ri);

                                        Send(newRosterIq);


                                    }
                                    else
                                    {

                                    }
                                }

                                ///Save friend Roster to Xml
                                this.m_Server.AccountManager.Save();

                                return;

                            }
                            else
                            {
                                friend = this.m_ClientAccount.FindFriend(rosterItem.Jid.ToString());
                                if (friend == null)
                                {
                                    friend = this.m_ClientAccount.AddFriend();
                                }

                                ///******************************************************
                                ///JID中已经包含有Company,Friend中是否还需要Company信息
                                ///******************************************************
                                friend.JID = rosterItem.Jid;
                                friend.Nick = rosterItem.Name;

                                friend.SubscriptionType = rosterItem.Subscription;
                                friend.SubscriptionStatus = int.Parse(rosterItem.Ask.ToString("D"));

                                foreach (Element groupItem in rosterItem.GetGroups())
                                {
                                    friend.AddGroup(groupItem.InnerXml);
                                }
                                friend.Save();


                                //if (friend.Groups.Count == 0)
                                //{
                                //    friend.AddGroup(friend.Company);
                                //}

                                // push roster set iq to all the resurce
                                RosterIq newRosterIq = new RosterIq(IqType.set);
                                newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                                RosterItem ri = new RosterItem();
                                if (rosterItem.Name == null || rosterItem.Name == string.Empty)
                                {
                                    ri.Name = rosterItem.Jid.User;
                                }
                                else
                                {
                                    ri.Name = rosterItem.Name;
                                }

                                ri.Jid = rosterItem.Jid;
                                ri.Subscription = SubscriptionType.none;

                                ///******************************************************
                                ///订阅用户的分组信息需要考虑?
                                ///******************************************************
                                foreach (Element groupItem in rosterItem.GetGroups())
                                {
                                    ri.AddGroup(groupItem.InnerXml);
                                }

                                newRosterIq.Query.AddRosterItem(ri);

                                //Push roster update to all client
                                //foreach (Account account in this.m_Server.ClientConnections.Keys)
                                //{
                                //    if (account.JID.Bare.ToLower() == this.m_ClientAccount.JID.Bare.ToLower())
                                //    {
                                //        //this.m_Server.ClientConnections[account].Send(newRosterIq);
                                //        SendToAllResource(account, newRosterIq);
                                //    }
                                //}

                                bSend = Send(this.m_ClientAccount, newRosterIq);
                                if (!bSend)
                                {

                                }

                            }
                        }
                        else
                        {
                            friend = this.m_ClientAccount.FindFriend(rosterItem.Jid.ToString());
                            if (friend == null)
                            {
                                friend = this.m_ClientAccount.AddFriend();

                                ///******************************************************
                                ///JID中已经包含有Company,Friend中是否还需要Company信息
                                ///******************************************************
                                friend.JID = rosterItem.Jid;
                                friend.SubscriptionType = SubscriptionType.none;
                                friend.SubscriptionStatus = -1;
                            }

                            friend.Nick = rosterItem.Name;

                            friend.Groups.Clear();

                            foreach (Element groupItem in rosterItem.GetGroups())
                            {
                                friend.AddGroup(groupItem.InnerXml);
                            }

                            friend.Save();

                            //if (friend.Groups.Count == 0)
                            //{
                            //    friend.AddGroup(friend.Company);
                            //}

                            // push roster set iq to all the resurce
                            RosterIq newRosterIq = new RosterIq(IqType.set);
                            newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                            RosterItem ri = new RosterItem();
                            if (rosterItem.Name == null || rosterItem.Name == string.Empty)
                            {
                                ri.Name = rosterItem.Jid.User;
                            }
                            else
                            {
                                ri.Name = rosterItem.Name;
                            }
                            ri.Jid = rosterItem.Jid;
                            ri.Subscription = friend.SubscriptionType;

                            ///******************************************************
                            ///订阅用户的分组信息需要考虑?
                            ///******************************************************
                            foreach (string strGroup in friend.Groups)
                            {
                                ri.AddGroup(strGroup);
                            }

                            newRosterIq.Query.AddRosterItem(ri);

                            //Push roster update to all client
                            //foreach (Account account in this.m_Server.ClientConnections.Keys)
                            //{
                            //    if (account.JID.Bare.ToLower() == this.m_ClientAccount.JID.Bare.ToLower())
                            //    {
                            //        //this.m_Server.ClientConnections[account].Send(newRosterIq);
                            //        SendToAllResource(account, newRosterIq);
                            //    }
                            //}

                            bSend = Send(this.m_ClientAccount, newRosterIq);
                            if (!bSend)
                            {

                            }

                        }


                        //Send Result IQ
                        IQ newIq = new IQ(IqType.result);
                        newIq.Namespace = agsXMPP.Uri.CLIENT;
                        newIq.Id = iq.Id;
                        //newIq.From = this.m_ClientAccount.JID;
                        //newIq.To = this.m_ClientAccount.JID;
                        Send(newIq);

                        ///Save friend Roster to Xml
                        this.m_Server.AccountManager.Save();
                    }

                }
            }
Esempio n. 2
0
            private void ProcessPresence(Presence presence)
            {
                bool bSend = false;
                #region subscribe
                if (presence.Type == PresenceType.subscribe)
                {
                    //RECV: <presence xmlns="jabber:client" type="subscribe" to="test2@localhost" />

                    //SEND: 
                    //<iq id="162" type="set">
                    //    <query xmlns="jabber:iq:roster">
                    //        <item jid="test2@localhost" name="test2" subscription="none" ask="subscribe"/>
                    //    </query>
                    //</iq>

                    //SEND: <presence xmlns="jabber:client" type="subscribe" to="test2@localhost" from="test@localhost" />

                    // push roster set iq to all the resurce
                    RosterIq newRosterIq = new RosterIq(IqType.set);
                    newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                    Jid subscribeJID = presence.To;

                    RosterItem ri = new RosterItem();
                    ri.Name = subscribeJID.User;
                    ri.Jid = subscribeJID;


                    Friend friend = this.m_ClientAccount.FindFriend(subscribeJID.ToString());
                    if (friend == null)
                    {

                    }
                    ///ask status change
                    friend.SubscriptionStatus = 0;

                    ri.Subscription = friend.SubscriptionType;
                    ri.Ask = AskType.subscribe;

                    foreach (string strGroup in friend.Groups)
                    {
                        ri.AddGroup(strGroup);
                    }

                    newRosterIq.Query.AddRosterItem(ri);

                    //Push roster update to all client
                    //foreach (Account account in this.m_Server.ClientConnections.Keys)
                    //{
                    //    if (account.JID.Bare.ToLower() == this.m_ClientAccount.JID.Bare.ToLower())
                    //    {
                    //        //this.m_Server.ClientConnections[account].Send(newRosterIq);
                    //        Send(account, newRosterIq);
                    //    }
                    //}

                    Send(newRosterIq);

                    Presence newPresence = new Presence();
                    newPresence.Namespace = agsXMPP.Uri.CLIENT;
                    newPresence.Type = PresenceType.subscribe;
                    newPresence.From = new Jid(this.m_ClientAccount.JID.Bare);
                    newPresence.To = presence.To;

                    /////路由信息
                    //account = new Account();
                    //account.Company = presence.To.Company;
                    //account.UserID = presence.To.User;

                    //if(this.m_Server.ClientConnections.ContainsKey(account))
                    //{
                    //    //this.m_Server.ClientConnections[account].Send(newPresence);
                    //    SendToAllResource(account, newPresence);
                    //}
                    //else
                    //{
                    //    this.m_Server.CachePresences.Add(newPresence.To, newPresence);
                    //}

                    bSend = Send(presence.To, newPresence);
                    if (!bSend)
                    {

                    }

                    //RosterIq newRosterIq = new RosterIq(IqType.set);

                    //RosterItem ri = new RosterItem();
                    //ri.Name = presence.To.User;
                    //ri.Jid = presence.To;
                    //ri.Subscription = SubscriptionType.none;
                    //ri.Ask = AskType.subscribe;
                    //newRosterIq.Query.AddRosterItem(ri);

                    //Send(newRosterIq);

                }
                #endregion
                #region subscribed
                else if (presence.Type == PresenceType.subscribed)
                {
                    //RECV: <presence xmlns="jabber:client" type="subscribed" to="test@localhost" />

                    //<iq id="178" type="set">
                    //    <query xmlns="jabber:iq:roster">
                    //        <item jid="test@localhost" name="test@localhost" subscription="from" />
                    //    </query>
                    //</iq>

                    //<iq id="181" type="set">
                    //    <query xmlns="jabber:iq:roster">
                    //        <item jid="test2@localhost" name="test2@localhost" subscription="to" />
                    //    </query>
                    //</iq>

                    //SEND: 
                    //<presence xmlns="jabber:client" type="subscribed" to="test@localhost" from="test2@localhost" />
                    //<presence xmlns="jabber:client" from="test2@localhost/MF" xml:lang="zh-cn" to="test@localhost/MF">
                    //    <priority>10</priority>
                    //</presence>

                    RosterIq newRosterIq = null;
                    RosterItem ri = null;

                    Jid userJID = presence.To;
                    Jid contactJID = this.m_ClientAccount.JID;

                    ///改变花名册的订阅状态
                    Friend user = this.m_ClientAccount.FindFriend(userJID.ToString());
                    if (user == null)
                    {
                        user = this.m_ClientAccount.AddFriend();
                        user.JID = userJID;
                        user.Nick = userJID.User;
                        user.SubscriptionType = SubscriptionType.none;
                        user.SubscriptionStatus = -1;
                    }

                    if (user.Nick == null || user.Nick == string.Empty)
                    {
                        user.Nick = userJID.User;
                    }

                    user.SubscriptionStatus = 1;
                    if (user.SubscriptionType == SubscriptionType.none)
                    {
                        user.SubscriptionType = SubscriptionType.from;
                    }
                    else if (user.SubscriptionType == SubscriptionType.to)
                    {
                        user.SubscriptionType = SubscriptionType.both;
                    }
                    else
                    {

                    }

                    //联系人花名册中的用户的订阅状态保存
                    user.Save();

                    // push roster set iq to all the resurce
                    newRosterIq = new RosterIq(IqType.set);
                    newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                    ri = new RosterItem();
                    ri.Name = userJID.User;
                    ri.Jid = userJID;
                    ri.Subscription = user.SubscriptionType;

                    foreach (string strGroup in user.Groups)
                    {
                        ri.AddGroup(strGroup);
                    }

                    newRosterIq.Query.AddRosterItem(ri);

                    bSend = Send(this.m_ClientAccount, newRosterIq);
                    if (!bSend)
                    {

                    }

                    Account userAccount = this.m_Server.AccountManager.FindAccount(userJID.ToString());
                    Friend contact = userAccount.FindFriend(contactJID.ToString());
                    if (contact == null)
                    {
                        contact = this.m_ClientAccount.AddFriend();
                        contact.JID = contactJID;
                        contact.Nick = contactJID.User;
                        contact.SubscriptionType = SubscriptionType.none;
                        contact.SubscriptionStatus = -1;
                    }

                    if (contact.Nick == null || contact.Nick == string.Empty)
                    {
                        contact.Nick = contactJID.User;
                    }

                    contact.SubscriptionStatus = 1;
                    if (contact.SubscriptionType == SubscriptionType.none)
                    {
                        contact.SubscriptionType = SubscriptionType.to;
                    }
                    else if (contact.SubscriptionType == SubscriptionType.from)
                    {
                        contact.SubscriptionType = SubscriptionType.both;
                    }
                    else
                    {

                    }

                    //用户花名册中的联系人的订阅状态保存
                    contact.Save();

                    // push roster set iq to all the resurce
                    newRosterIq = new RosterIq(IqType.set);
                    newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                    ri = new RosterItem();
                    ri.Name = contact.Nick;
                    ri.Jid = contact.JID;
                    ri.Subscription = contact.SubscriptionType;

                    foreach (string strGroup in contact.Groups)
                    {
                        ri.AddGroup(strGroup);
                    }

                    newRosterIq.Query.AddRosterItem(ri);

                    bSend = Send(userAccount, newRosterIq);
                    if (!bSend)
                    {

                    }

                    //<presence xmlns="jabber:client" type="subscribed" to="test@localhost" from="test2@localhost" />

                    Presence newPresence = new Presence();
                    newPresence.Namespace = agsXMPP.Uri.CLIENT;
                    newPresence.Type = PresenceType.subscribed;
                    newPresence.From = new Jid(this.m_ClientAccount.JID.Bare);
                    newPresence.To = presence.To;

                    bSend = Send(presence.To, newPresence);
                    if (!bSend)
                    {

                    }

                    //<presence xmlns="jabber:client" from="test2@localhost/MF" xml:lang="zh-cn" to="test@localhost/MF">
                    //    <priority>10</priority>
                    //</presence>

                    newPresence.RemoveAttribute("type");
                    newPresence.Language = this.objClientlanguage.Name;
                    newPresence.Priority = 10;
                    Send(presence.To, newPresence);

                }
                #endregion
                #region unsubscribe
                else if (presence.Type == PresenceType.unsubscribe)
                {



                }
                #endregion
                #region unsubscribed
                else if (presence.Type == PresenceType.unsubscribed)
                {
                    //RECV: 
                    //    <presence xmlns="jabber:client" type="unsubscribed" to="test@localhost" />
                    //SEND: 
                    //    <iq id="168" type="set">
                    //        <query xmlns="jabber:iq:roster">
                    //            <item jid="test2@localhost" name="test2" subscription="none" />
                    //        </query>
                    //    </iq>
                    //SEND: <presence xmlns="jabber:client" type="unsubscribed" to="test@localhost/MF" from="test2@localhost" />

                    //SEND: <presence from="test@localhost/MF" xml:lang="zh-cn" type="unavailable" to="test2@localhost/MF" />

                    // push roster set iq to all the resurce
                    RosterIq newRosterIq = null;
                    RosterItem ri = null;

                    newRosterIq = new RosterIq(IqType.set);
                    newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                    Jid subscribeJID = presence.To;

                    ri = new RosterItem();
                    ri.Name = subscribeJID.User;
                    ri.Jid = subscribeJID;

                    Friend friend = this.m_ClientAccount.FindFriend(subscribeJID.ToString());
                    if (friend != null)
                    {
                        ///ask status change
                        friend.SubscriptionStatus = 1;
                        friend.Save();

                        ri.Subscription = friend.SubscriptionType;

                        foreach (string strGroup in friend.Groups)
                        {
                            ri.AddGroup(strGroup);
                        }
                    }
                    else
                    {
                        ri.Subscription = SubscriptionType.none;
                    }

                    newRosterIq.Query.AddRosterItem(ri);

                    Send(newRosterIq);

                    ///to user
                    newRosterIq = new RosterIq(IqType.set);
                    newRosterIq.Namespace = agsXMPP.Uri.CLIENT;

                    ri = new RosterItem();

                    Account userAccount = this.m_Server.AccountManager.FindAccount(presence.To.ToString());
                    Friend contactFriend = userAccount.FindFriend(this.m_ClientAccount.JID.ToString());

                    ri.Name = contactFriend.Nick;
                    ri.Jid = contactFriend.JID;
                    ri.Subscription = contactFriend.SubscriptionType;

                    contactFriend.SubscriptionStatus = 1;
                    contactFriend.Save();

                    //Push roster update to all client
                    bSend = Send(presence.To, newRosterIq);
                    if (!bSend)
                    {

                    }

                    Presence newPresence = new Presence();
                    newPresence.Namespace = agsXMPP.Uri.CLIENT;
                    newPresence.Type = PresenceType.unsubscribed;
                    newPresence.From = new Jid(this.m_ClientAccount.JID.Bare);
                    newPresence.To = presence.To;

                    ///路由信息
                    bSend = Send(presence.To, newPresence);
                    if (!bSend)
                    {
                        this.m_Server.CachePresences.Add(newPresence.To, newPresence);
                    }

                    newPresence.Type = PresenceType.unavailable;
                    newPresence.RemoveAttribute("xmlns");
                    newPresence.Language = this.objClientlanguage.Name;

                    bSend = Send(presence.To, newPresence);
                    if (!bSend)
                    {

                    }

                }
                #endregion
                #region unavailable
                else if (presence.Type == PresenceType.unavailable)
                {
                    //<presence xmlns="jabber:client" to="*****@*****.**" type="unavailable" />
                    //<presence from='[email protected]/pda' to='[email protected]/thirdwitch'type='unavailable'/>

                    //<presence
                    //    from='[email protected]/thirdwitch'
                    //    to='[email protected]/desktop'
                    //    type='unavailable'>
                    //  <x xmlns='http://jabber.org/protocol/muc#user'>
                    //    <item affiliation='member' role='none'/>
                    //  </x>
                    //</presence>

                    MucService muc = this.m_Server.GetMucService();
                    if(muc != null)
                    {
                        foreach (KeyValuePair<string, ChatRoom> item in muc.GetRooms())
                        {
                            if (item.Value.JID.ToString() == presence.To.Bare.ToString())
                            {
                                User from = item.Value.FindOnline(this.m_ClientAccount.JID.Bare);
                                if (from == null)
                                {
                                    return;
                                }

                                Presence newPresence = new Presence();
                                newPresence.Type = PresenceType.unavailable;
                                newPresence.From = new Jid(item.Value.JID.ToString() + "/" + from.Nick);
                                foreach (User user in item.Value.GetOnlines())
                                {
                                    newPresence.To = user.JID;

                                    Send(newPresence.To, newPresence);
                                }

                                item.Value.Exit(from);

                                return;
                            }

                        }

                    }

                    return;
                }
                #endregion
                #region else
                else
                {
                    #region showType.Noe
                    if (presence.Show == ShowType.NONE)
                    {
                        ///groupchat roster presence
                        if (presence.To != null)
                        {
                            MucService muc = this.m_Server.GetMucService();
                            if(muc != null)
                            {
                                if (muc.JID.Bare.ToLower() == presence.To.Server.ToLower())
                                {
                                    foreach (KeyValuePair<string, ChatRoom> item in muc.GetRooms())
                                    {
                                        if (item.Value.JID.ToString().ToLower() == presence.To.Bare.ToLower())
                                        {
                                            User login = new User();
                                            login.Nick = presence.To.Resource;
                                            login.Role = agsXMPP.protocol.x.muc.Role.participant;
                                            login.Affiliation = agsXMPP.protocol.x.muc.Affiliation.member;
                                            login.JID = new Jid(this.m_ClientAccount.JID.ToString() + "/" + this.strBindResource);

                                            Presence newPresence = null;

                                            List<User> onlines = item.Value.GetOnlines();
                                            if (onlines == null)
                                            {
                                                item.Value.Enter(login);
                                                return;
                                            }

                                            foreach (User user in onlines)
                                            {
                                                newPresence = new Presence();
                                                newPresence.From = new Jid(presence.To.Bare + "/" + user.Nick);
                                                newPresence.To = login.JID;

                                                newPresence.MucUser = new agsXMPP.protocol.x.muc.User();
                                                newPresence.MucUser.Item = new agsXMPP.protocol.x.muc.Item(user.Affiliation, user.Role);

                                                Send(newPresence.To, newPresence);


                                                newPresence = new Presence();
                                                newPresence.From = new Jid(presence.To.Bare + "/" + login.Nick); ;
                                                newPresence.To = user.JID;

                                                newPresence.MucUser = new agsXMPP.protocol.x.muc.User();
                                                newPresence.MucUser.Item = new agsXMPP.protocol.x.muc.Item(login.Affiliation, login.Role);

                                                Send(newPresence.To, newPresence);

                                            }

                                            item.Value.Enter(login);
                                        }
                                    }

                                    return;

                                }

                            }
                        }

                        foreach (Friend friend in this.m_ClientAccount.Friends)
                        {

                            Account account = this.m_Server.AccountManager.FindAccount(friend.JID.ToString());
                            if (account == null)
                            {
                                continue;
                            }

                            if (!this.m_Server.ClientConnections.ContainsKey(account))
                            {
                                continue;
                            }

                            Presence newPresence = new Presence();
                            //newPresence.From = presence.From;
                            //newPresence.To = presence.To;

                            newPresence.Priority = presence.Priority;

                            SubscriptionType subscriptionType = friend.SubscriptionType;

                            if (subscriptionType == SubscriptionType.from)
                            {
                                newPresence.From = account.JID;
                                newPresence.To = this.m_ClientAccount.JID;
                                Send(newPresence);
                            }
                            else if (subscriptionType == SubscriptionType.to)
                            {
                                newPresence.From = this.m_ClientAccount.JID;
                                newPresence.To = account.JID;

                                Send(account, newPresence);

                            }
                            else if (subscriptionType == SubscriptionType.both)
                            {
                                newPresence.From = account.JID;
                                newPresence.To = this.m_ClientAccount.JID;
                                Send(newPresence);

                                newPresence.SwitchDirection();
                                //this.m_Server.ClientConnections[account].Send(newPresence);
                                Send(account, newPresence);
                            }
                            else
                            {

                            }
                        }

                    }
                    #endregion
                    #region else
                    else
                    {

                    }
                    #endregion

                }
                #endregion

                this.m_Server.AccountManager.Save();

            }