/// <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); }
/// <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(); }
/// <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; }
/// <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; }