Пример #1
0
 public IqEventArgs(Iq stanza)
 {
     stanza.ThrowIfNull <Iq>("stanza");
     this.Stanza = stanza;
 }
Пример #2
0
 /// <summary>
 /// Initializes a new instance of the IqEventArgs class.
 /// </summary>
 /// <param name="stanza">The IQ stanza on whose behalf the event is
 /// raised.</param>
 /// <exception cref="ArgumentNullException">The stanza parameter is null.</exception>
 public IqEventArgs(Iq stanza)
 {
     stanza.ThrowIfNull("stanza");
     Stanza = stanza;
 }
Пример #3
0
		/// <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();
				// Raise the error event.
				if(!disposed)
					Error.Raise(this, new ErrorEventArgs(e));
			}
		}
Пример #4
0
		/// <summary>
		/// Sends an IQ response for the IQ request with the specified id.
		/// </summary>
		/// <param name="response">The IQ response to send.</param>
		/// <exception cref="ArgumentNullException">The response parameter is
		/// null.</exception>
		/// <exception cref="ArgumentException">The Type property of the response
		/// parameter is not IqType.Result or IqType.Error.</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.</exception>
		public void IqResponse(Iq response) {
			AssertValid();
			response.ThrowIfNull("response");
			if (response.Type != IqType.Result && response.Type != IqType.Error)
				throw new ArgumentException("The IQ type must be either 'result' or 'error'.");
			Send(response);
		}
Пример #5
0
		/// <summary>
		/// Performs an IQ set/get request asynchronously and optionally invokes a
		/// callback method when the IQ response comes in.
		/// </summary>
		/// <param name="request">The IQ request to send.</param>
		/// <param name="callback">A callback method which is invoked once the
		/// IQ response from the server comes in.</param>
		/// <returns>The ID value of the pending IQ stanza request.</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="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.</exception>
		public string IqRequestAsync(Iq request, Action<string, Iq> callback = null) {
			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'.");
			request.Id = GetId();
			// Register the callback.
			if (callback != null)
				iqCallbacks[request.Id] = callback;
			Send(request);
			return request.Id;
		}
Пример #6
0
		/// <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) {
			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'.");
			// 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 },
				millisecondsTimeout);
			if (index == WaitHandle.WaitTimeout)
				throw new TimeoutException();
			// 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();
		}
Пример #7
0
		/// <summary>
		/// Handles incoming IQ responses for previously issued IQ requests.
		/// </summary>
		/// <param name="iq">The received IQ response stanza.</param>
		void HandleIqResponse(Iq iq) {
			string id = iq.Id;
			AutoResetEvent ev;
			Action<string, Iq> cb;
			iqResponses[id] = iq;
			// Signal the event if it's a blocking call.
			if (waitHandles.TryRemove(id, out ev))
				ev.Set();
			// Call the callback if it's an asynchronous call.
			else if (iqCallbacks.TryRemove(id, out cb))
				Task.Factory.StartNew(() => { cb(id, iq); });
		}