예제 #1
0
 public XmppSessionArgs(XmppSession session)
 {
     if (session == null)
     {
         throw new ArgumentNullException("session");
     }
     Session = session;
 }
        public void AddSession(XmppSession session)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }

            sessions.TryAdd(session.Jid, session);
        }
 private void SoftInvokeEvent(EventHandler <XmppSessionArgs> eventHandler, XmppSession session)
 {
     try
     {
         var handler = eventHandler;
         if (handler != null)
         {
             handler(this, new XmppSessionArgs(session));
         }
     }
     catch { }
 }
 public void AddSession(XmppSession session)
 {
     if (session == null)
     {
         throw new ArgumentNullException("session");
     }
     try
     {
         locker.EnterWriteLock();
         sessions.Add(session.Jid, session);
     }
     finally
     {
         locker.ExitWriteLock();
     }
 }
        public void SetSessionPresence(XmppSession session, Presence presence)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }
            if (presence == null)
            {
                throw new ArgumentNullException("presence");
            }

            var oldPresence = session.Presence;

            session.Presence = presence;
            if (!IsAvailablePresence(oldPresence) && IsAvailablePresence(presence))
            {
                SoftInvokeEvent(SessionAvailable, session);
            }
            if (IsAvailablePresence(oldPresence) && !IsAvailablePresence(presence))
            {
                SoftInvokeEvent(SessionUnavailable, session);
            }
        }
예제 #6
0
 public void SendTo(XmppSession to, Node node)
 {
     if (to == null) throw new ArgumentNullException("to");
     SendTo(to.Stream, node);
 }
예제 #7
0
        public void AddXmppConnection(string connectionId, string userName, byte state, int tenantId)
        {
            try
            {
                _log.DebugFormat("Add Xmpp Connection: connectionId={0}, userName={1}, state={2}, tenantId={3}", connectionId, userName, state, tenantId);
                var jid = GetJid(userName, tenantId, SignalRHelper.SIGNALR_RESOURCE);
                var listener = (SignalRXmppListener)((XmppGateway)_xmppServer.GetService(typeof(IXmppReceiver))).GetXmppListener("SignalR Listener");
                if (listener.GetXmppConnection(connectionId) != null)
                {
                    RemoveXmppConnection(connectionId, userName, tenantId);
                }
                listener.AddXmppConnection(connectionId, _xmppServer);
                var xmppStream = ((XmppStreamManager)_xmppServer.GetService(typeof(XmppStreamManager))).GetOrCreateNewStream(connectionId);
                xmppStream.Authenticate(userName);
                string domain = CoreContext.TenantManager.GetTenant(tenantId).TenantDomain;
                if (fromTeamlabToOnlyOffice == "true" && domain.EndsWith(fromServerInJid))
                {
                    int place = domain.LastIndexOf(fromServerInJid);
                    if (place >= 0)
                    {
                        domain = domain.Remove(place, fromServerInJid.Length).Insert(place, toServerInJid);
                    }
                }
                xmppStream.Domain = domain;
                xmppStream.Connected = true;
                xmppStream.BindResource(SignalRHelper.SIGNALR_RESOURCE);

                var handler = _xmppServer.HandlerManager.HandlerStorage.GetStreamStartHandlers(jid)[0];
                var stream = new Stream
                {
                    To = new Jid(jid.Server),
                    Namespace = "http://etherx.jabber.org/streams",
                    Version = "1.6",
                    Language = string.Empty
                };

                handler.StreamStartHandle(xmppStream, stream, null);

                var session = new XmppSession(jid, xmppStream)
                {
                    RosterRequested = false,
                    Active = true,
                    IsSignalRFake = true
                };

                ((XmppSessionManager)_xmppServer.GetService(typeof(XmppSessionManager))).AddSession(session);

                var presence = new Presence(SignalRHelper.GetShowType(state), String.Empty, SignalRHelper.PRIORITY)
                {
                    From = jid,
                    Type = SignalRHelper.GetPresenceType(state)
                };

                _xmppServer.SessionManager.SetSessionPresence(session, presence);

                var sender = (IXmppSender)_xmppServer.GetService(typeof(IXmppSender));
                var sessions = _xmppServer.SessionManager.GetSessions().Where(s => s.Id != session.Id).ToArray();
                sender.Broadcast(sessions, session.Presence);

                var offlineMessages = _xmppServer.StorageManager.OfflineStorage.GetOfflineMessages(jid);
                if (offlineMessages.Count > 0)
                {
                    var users = new List<string>();
                    for (int i = 0; i < offlineMessages.Count; i++)
                    {
                        var from = offlineMessages[i].From;
                        var name = from.User != null ? from.User.ToLowerInvariant() : string.Empty;
                        if (!users.Contains(name))
                        {
                            users.Add(name);
                        }
                    }
                    _reverseJabberServiceClient.SendOfflineMessages(userName, users, tenantId);
                    _xmppServer.StorageManager.OfflineStorage.RemoveAllOfflineMessages(jid);
                }
            }
            catch (Exception e)
            {
                _log.ErrorFormat("Unexpected error, userName = {0}, {1}, {2}, {3}", userName,
                    e, e.StackTrace, e.InnerException != null ? e.InnerException.Message : string.Empty);
            }
        }
예제 #8
0
		private void HandlePresence(Presence presence, XmppSession session)
		{
			var toRosterItem = GetUserRosterItem(presence.From, presence.To);
			var fromRosterItem = GetUserRosterItem(presence.To, presence.From);

			var stateOut = GetState(fromRosterItem, toRosterItem);
			var stateIn = GetState(toRosterItem, fromRosterItem);

			bool bRoute = false;
			bool bAutoReply = false;
			bool bMutualCreating =
				(fromRosterItem.Subscribtion == SubscriptionType.to && toRosterItem.Subscribtion == SubscriptionType.from) ||
				(fromRosterItem.Subscribtion == SubscriptionType.from && toRosterItem.Subscribtion == SubscriptionType.to);
			bool bMutualExists = (fromRosterItem.Subscribtion == SubscriptionType.both && toRosterItem.Subscribtion == SubscriptionType.both);

			var newType = presence.Type;
			if (newType == PresenceType.subscribe)
			{
				if (bMutualCreating)
				{
					if (toRosterItem.Subscribtion == SubscriptionType.from && toRosterItem.Ask == AskType.NONE)
					{
						//Push roster with ASK=subscribe
						toRosterItem.Ask = AskType.subscribe;
						UpdateItems(presence, ref fromRosterItem, ref toRosterItem);
						//Push
						sender.Broadcast(
							sessionManager.GetBareJidSessions(presence.From),
							toRosterItem.GetRosterIq(presence.From)
						);
						//Forward
						presence.To = new Jid(presence.To.Bare);
						bool sended = sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence);

						if (!sended) StoreOffline(presence);
					}
				}
				else
				{
					//it's inbound for user 'to'
					ChangeInboundPresence(stateIn, toRosterItem, fromRosterItem, newType, out bRoute, out bAutoReply);
					if (bAutoReply)
					{
						//Reply with 'subscribed'
						var autoPresence = new Presence();
						autoPresence.To = presence.From;
						autoPresence.From = presence.To;
						autoPresence.Type = PresenceType.subscribed;
						sender.Broadcast(sessionManager.GetBareJidSessions(autoPresence.To), autoPresence);
					}
					else
					{
						if (bRoute)
						{
							//Send to 'to' user
							presence.To = new Jid(presence.To.Bare);
							bool sended = sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence);
							if (!sended) StoreOffline(presence);

							//State is changed init roster push
							UpdateItems(presence, ref fromRosterItem, ref toRosterItem);
							sender.Broadcast(
								sessionManager.GetBareJidSessions(presence.From),
								toRosterItem.GetRosterIq(presence.From)
							);
							//Send result stanza
							sender.SendTo(session, new IQ(IqType.result));
						}
					}
				}
			}
			else if (newType == PresenceType.subscribed)
			{
				if (bMutualCreating)
				{
					if (fromRosterItem.Subscribtion == SubscriptionType.from && fromRosterItem.Ask == AskType.subscribe)
					{
						//Send roster to contact with both to 'from'
						//Create both subscription

						//Send subscribed back
						toRosterItem.Subscribtion = SubscriptionType.both;
						toRosterItem.Ask = AskType.NONE;
						UpdateItems(presence, ref fromRosterItem, ref toRosterItem);
						sender.Broadcast(
							sessionManager.GetBareJidSessions(presence.From),
							toRosterItem.GetRosterIq(presence.From)
						);
						sender.SendTo(session, new IQ(IqType.result));
						//fwd
						presence.To = new Jid(presence.To.Bare);
						if (!sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence))
						{
							StoreOffline(presence);
						}
						//Send contact with both
						fromRosterItem.Subscribtion = SubscriptionType.both;
						fromRosterItem.Ask = AskType.NONE;
						UpdateItems(presence, ref fromRosterItem, ref toRosterItem);
						sender.Broadcast(
							sessionManager.GetBareJidSessions(presence.To),
							fromRosterItem.GetRosterIq(presence.To)
						);
						//Send to session presence
						if (session.Presence != null)
						{
							sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), session.Presence);
						}
					}
				}
				else
				{
					//It's outbound for user 'from'
					ChangeOutboundPresence(stateOut, toRosterItem, fromRosterItem, newType, out bRoute);
					//Roster oush for 'from'
					if (bRoute)
					{
						//State is changed init roster push
						UpdateItems(presence, ref fromRosterItem, ref toRosterItem);
						sender.Broadcast(
							sessionManager.GetBareJidSessions(presence.From),
							toRosterItem.GetRosterIq(presence.From)
						);
						//Send result stanza
						sender.SendTo(session, new IQ(IqType.result)); //dont send
					}
					//It's inbound for user 'to'
					if ((fromRosterItem.Subscribtion == SubscriptionType.none || fromRosterItem.Subscribtion == SubscriptionType.from) &&
						fromRosterItem.Ask == AskType.subscribe)
					{
						ChangeInboundPresence(stateIn, fromRosterItem, toRosterItem, newType, out bRoute, out bAutoReply);
						if (bRoute)
						{
							presence.To = new Jid(presence.To.Bare);
							if (sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence))
							{
								StoreOffline(presence);
							}
							else
							{
								if (session.Presence != null)
								{
									sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), session.Presence);
								}
							}
							//State is changed init roster push
							UpdateItems(presence, ref fromRosterItem, ref toRosterItem);
							sender.Broadcast(
								sessionManager.GetBareJidSessions(presence.To),
								fromRosterItem.GetRosterIq(presence.To));
						}
					}
				}
			}
			else if (newType == PresenceType.unsubscribe)
			{
				//Get to roster
				//it's inbound for user 'to'
				ChangeInboundPresence(stateIn, toRosterItem, fromRosterItem, newType, out bRoute, out bAutoReply);
				if (bAutoReply)
				{
					//Reply with 'subscribed'
					Presence autoPresence = new Presence();
					autoPresence.To = presence.From;
					autoPresence.From = presence.To;
					autoPresence.Type = PresenceType.unsubscribed;
					sender.Broadcast(sessionManager.GetBareJidSessions(autoPresence.To), autoPresence);
					//Route
					presence.To = new Jid(presence.To.Bare);
					if (!sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence))
					{
						StoreOffline(presence);
					}
				}
			}
			else if (newType == PresenceType.unsubscribed)
			{


				//It's outbound for user 'from'
				ChangeOutboundPresence(stateOut, toRosterItem, fromRosterItem, newType, out bRoute);
				//Roster oush for 'from'
				if (bRoute)
				{
					//State is changed init roster push
					UpdateItems(presence, ref fromRosterItem, ref toRosterItem);
					sender.Broadcast(
						sessionManager.GetBareJidSessions(presence.From),
						toRosterItem.GetRosterIq(presence.From));
					//Send result stanza
					sender.SendTo(session, new IQ(IqType.result)); //dont send
				}

				ChangeInboundPresence(stateIn, fromRosterItem, toRosterItem, newType, out bRoute, out bAutoReply);
				if (bRoute)
				{
					presence.To = new Jid(presence.To.Bare);
					if (!sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence))
					{
						StoreOffline(presence);
					}
					else
					{
						sender.Broadcast(
							sessionManager.GetBareJidSessions(presence.To),
							new Presence() { Type = PresenceType.unavailable, From = presence.From });
					}
					//State is changed init roster push
					UpdateItems(presence, ref fromRosterItem, ref toRosterItem);
					sender.Broadcast(
						sessionManager.GetBareJidSessions(presence.To),
						fromRosterItem.GetRosterIq(presence.To));
				}

			}

			UpdateItems(presence, ref fromRosterItem, ref toRosterItem);
		}
예제 #9
0
 private void SendOfflinePresences(XmppSession session)
 {
     foreach (var presence in offlineStore.GetOfflinePresences(session.Jid))
     {
         sender.SendTo(session, presence);
     }
     offlineStore.RemoveAllOfflinePresences(session.Jid);
 }
예제 #10
0
        private void SendRosterPresences(XmppSession session)
        {
            //It's correct!
            //Get other statuses
            foreach (var ri in rosterStore.GetRosterItems(session.Jid))
            {
                //"none" -- the user does not have a subscription to the contact's presence information, and the contact does not have a subscription to the user's presence information
                //"to" -- the user has a subscription to the contact's presence information, but the contact does not have a subscription to the user's presence information
                //"from" -- the contact has a subscription to the user's presence information, but the user does not have a subscription to the contact's presence information
                //"both" -- both the user and the contact have subscriptions to each other's presence information
                if (ri.Subscribtion == SubscriptionType.to || ri.Subscribtion == SubscriptionType.both)
                {
                    foreach (var contactSession in sessionManager.GetBareJidSessions(ri.Jid))
                    {
                        if (contactSession.Presence != null)
                        {
                            //Send roster contact presence to newly availible session
                            contactSession.Presence.To = null;//To no one
                            sender.SendTo(session, contactSession.Presence);

                            if (contactSession.GetRosterTime.AddMinutes(1) < DateTime.UtcNow)
                            {
                                //Send roster push
                                var roster = new Roster();
                                roster.AddRosterItem(rosterStore.GetRosterItem(contactSession.Jid, session.Jid).ToRosterItem());
                                var iq = new IQ
                                {
                                    Type = IqType.set,
                                    Namespace = Uri.SERVER,
                                    Id = UniqueId.CreateNewId(),
                                    To = contactSession.Jid,
                                    Query = roster
                                };
                                sender.SendTo(contactSession, iq);
                            }
                        }
                    }
                }
            }
            var server = new Presence() { Type = PresenceType.available, From = new Jid(session.Jid.Server) };
            sender.SendTo(session, server);
        }
예제 #11
0
        private void SendOfflineMessages(XmppSession session)
        {
            if (!session.IsSignalRFake)
            {
                var domain = session.Stream.Domain;
                foreach (var m in offlineStore.GetOfflineMessages(session.Jid))
                {
                    var delay = new Element("delay");
                    delay.SetNamespace("urn:xmpp:delay");
                    delay.SetAttribute("From", domain);
                    delay.SetAttribute("stamp", Time.Date(m.XDelay.Stamp));
                    delay.Value = "Offline Storage";
                    m.AddChild(delay);

                    m.XDelay.From = new Jid(domain);
                    m.XDelay.Value = "Offline Storage";

                    sender.SendTo(session, m);
                }
                offlineStore.RemoveAllOfflineMessages(session.Jid);
            }
        }
예제 #12
0
 private void SoftInvokeEvent(EventHandler<XmppSessionArgs> eventHandler, XmppSession session)
 {
     try
     {
         var handler = eventHandler;
         if (handler != null) handler(this, new XmppSessionArgs(session));
     }
     catch { }
 }
예제 #13
0
        public void SetSessionPresence(XmppSession session, Presence presence)
        {
            if (session == null) throw new ArgumentNullException("session");
            if (presence == null) throw new ArgumentNullException("presence");

            var oldPresence = session.Presence;
            session.Presence = presence;
            if (!IsAvailablePresence(oldPresence) && IsAvailablePresence(presence))
            {
                SoftInvokeEvent(SessionAvailable, session);
            }
            if (IsAvailablePresence(oldPresence) && !IsAvailablePresence(presence))
            {
                SoftInvokeEvent(SessionUnavailable, session);
            }
        }
예제 #14
0
 public void AddSession(XmppSession session)
 {
     if (session == null) throw new ArgumentNullException("session");
     try
     {
         locker.EnterWriteLock();
         sessions.Add(session.Jid, session);
     }
     finally
     {
         locker.ExitWriteLock();
     }
 }
예제 #15
0
		public XmppSessionArgs(XmppSession session)
		{
			if (session == null) throw new ArgumentNullException("session");
			Session = session;
		}