コード例 #1
0
ファイル: XmppCore.cs プロジェクト: vanklompf/Sharp.Xmpp
		/// <summary>
		/// Performs an IQ set/get request and blocks until the response IQ comes in.
		/// </summary>
		/// <param name="request">The IQ request to send.</param>
		/// <param name="millisecondsTimeout">The number of milliseconds to wait
		/// for the arrival of the IQ response or -1 to wait indefinitely.</param>
		/// <returns>The IQ response sent by the server.</returns>
		/// <exception cref="ArgumentNullException">The request parameter is null.</exception>
		/// <exception cref="ArgumentException">The type parameter is not IqType.Set
		/// or IqType.Get.</exception>
		/// <exception cref="ArgumentOutOfRangeException">The value of millisecondsTimeout
		/// is a negative number other than -1, which represents an indefinite
		/// timeout.</exception>
		/// <exception cref="ObjectDisposedException">The XmppCore object has been
		/// disposed.</exception>
		/// <exception cref="InvalidOperationException">The XmppCore instance is not
		/// connected to a remote host.</exception>
		/// <exception cref="IOException">There was a failure while writing to the
		/// network, or there was a failure reading from the network.</exception>
		/// <exception cref="TimeoutException">A timeout was specified and it
		/// expired.</exception>
		public Iq IqRequest(Iq request, int millisecondsTimeout = -1) {
            int timeOut = -1;
            AssertValid();
			request.ThrowIfNull("request");
			if (request.Type != IqType.Set && request.Type != IqType.Get)
				throw new ArgumentException("The IQ type must be either 'set' or 'get'.");
            if (millisecondsTimeout == -1)
            {
                timeOut = millisecondsDefaultTimeout;
            }
            else timeOut = millisecondsTimeout;        
            // Generate a unique ID for the IQ request.
			request.Id = GetId();
			AutoResetEvent ev = new AutoResetEvent(false);
			Send(request);
			// Wait for event to be signaled by task that processes the incoming
			// XML stream.
			waitHandles[request.Id] = ev;
			int index = WaitHandle.WaitAny(new WaitHandle[] { ev, cancelIq.Token.WaitHandle },
                timeOut);
            if (index == WaitHandle.WaitTimeout)
            {
                //An entity that receives an IQ request of type "get" or "set" MUST reply with an IQ response of type 
                //"result" or "error" (the response MUST preserve the 'id' attribute of the request). 
                //http://xmpp.org/rfcs/rfc3920.html#stanzas
                //if (request.Type == IqType.Set || request.Type == IqType.Get)

                //Make sure that its a request towards the server and not towards any client
                var ping = request.Data["ping"];

                if (request.To.Domain == Jid.Domain && (request.To.Node == null || request.To.Node == "") && (ping != null && ping.NamespaceURI == "urn:xmpp:ping"))
                {
                    Connected = false;
                    var e=  new XmppDisconnectionException("Timeout Disconnection happened at IqRequest");
                    if (!disposed)
                        Error.Raise(this, new ErrorEventArgs(e));
                    //throw new TimeoutException();
                }

                //This check is somehow not really needed doue to the IQ must be either set or get
            }
			// Reader task errored out.
			if (index == 1)
				throw new IOException("The incoming XML stream could not read.");
			// Fetch response stanza.
			Iq response;
			if (iqResponses.TryRemove(request.Id, out response))
				return response;
			// Shouldn't happen.      
            	
            throw new InvalidOperationException();
		}
コード例 #2
0
ファイル: XmppCore.cs プロジェクト: vanklompf/Sharp.Xmpp
		/// <summary>
		/// Listens for incoming XML stanzas and raises the appropriate events.
		/// </summary>
		/// <remarks>This runs in the context of a separate thread. In case of an
		/// exception, the Error event is raised and the thread is shutdown.</remarks>
		void ReadXmlStream() {
			try {
				while (true) {
                    XmlElement elem = parser.NextElement("iq", "message", "presence");
					// Parse element and dispatch.
					switch (elem.Name) {
						case "iq":
							Iq iq = new Iq(elem);
							if (iq.IsRequest)
								stanzaQueue.Add(iq);
							else
								HandleIqResponse(iq);
							break;
						case "message":
							stanzaQueue.Add(new Message(elem));
							break;
						case "presence":
							stanzaQueue.Add(new Presence(elem));
							break;
					}
				}
			} catch (Exception e) {
				// Shut down the dispatcher task.
				cancelDispatch.Cancel();
				cancelDispatch = new CancellationTokenSource();
				// Unblock any threads blocking on pending IQ requests.
				cancelIq.Cancel();
				cancelIq = new CancellationTokenSource();
                //Add the failed connection
                if ((e is IOException) || (e is XmppDisconnectionException))
                {
                    Connected = false;
                    var ex = new XmppDisconnectionException(e.ToString());
                    e = ex;
                }
				// Raise the error event.
				if(!disposed)
					Error.Raise(this, new ErrorEventArgs(e));
			}
		}