Exemplo n.º 1
0
        public async Task <StanzaResult> OnStanzaReceivedAsync(Stanza stanza)
        {
            if (stanza.Element.Name == Xmlns.Streams.Stream)
            {
                if (State.HasDocumentTag)
                {
                    return(new StanzaResult(StreamAction.Close, Stanza.FromFullElement(
                                                new XElement(Xmlns.Streams.Error, new XElement(Xmlns.Client.Namespace + "bad-format")))));
                }
                else
                {
                    State.HasDocumentTag = true;
                    var element = new XElement(Xmlns.Streams.Stream,
                                               new XAttribute(XNamespace.Xmlns + "stream", Xmlns.Streams.Stream.NamespaceName),
                                               new XAttribute("xmlns", Xmlns.Client.Namespace.NamespaceName),
                                               new XAttribute(Xmlns.Attr.Version, "1.0"));

                    var features = new XElement(Xmlns.Streams.Features);
                    element.Add(features);

                    foreach (var feat in State.Features.Values)
                    {
                        var actor = ActorProxy.Create <IStreamFeature>(feat, Constants.ApplicationName);
                        element.Add(await actor.CreateDescriptiveElementAsync());
                    }

                    return(new StanzaResult(Stanza.FromOpeningTag(element)));
                }
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Accepts the connection.
        /// </summary>
        public async void Open()
        {
            using (_socket)
            {
                Write();

                try
                {
                    _client = ActorProxy.Create <IXmlConnection>(ActorId.NewId(), Constants.ApplicationName, Constants.ActorNames.UnboundClient);
                    await _client.SubscribeAsync(this);
                }
                catch (Exception e)
                {
                    ServiceEventSource.Current.ClientConnectionFailure(_socket.Identifier, e.ToString());
                    return;
                }

                while (!_cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        await CreateXmlAsync();

                        var element = await ReadStartElementAsync(_cancellationToken);

                        var stanza = Stanza.FromOpeningTag(element);

                        while (!_cancellationToken.IsCancellationRequested)
                        {
                            var result = await _client.OnStanzaReceivedAsync(stanza);

                            // Remove stanza elements from the document once we are
                            // done with them.
                            if (!stanza.OpeningTagOnly)
                            {
                                stanza.Element.Remove();
                            }

                            if (result != null)
                            {
                                if (result.Response != null)
                                {
                                    await WriteStanzaAsync(result.Response);
                                }

                                switch (result.StreamAction)
                                {
                                case StreamAction.Close: await CloseAsync(); return;

                                case StreamAction.Abort: return;

                                case StreamAction.StartTls: await StartTlsAsync(); break;
                                }

                                if ((int)result.StreamAction >= (int)StreamAction.Reset)
                                {
                                    break;
                                }
                            }

                            element = await ReadFullElementAsync(_cancellationToken);

                            stanza = Stanza.FromFullElement(element);
                        }
                    }
                    catch (Exception e)
                    {
                        var result = await _client.OnErrorOccurredAsync(e);

                        if (result != null && result.Response != null)
                        {
                            await WriteStanzaAsync(result.Response);
                        }

                        // Errors at this level always terminate the connection.
                        return;
                    }
                }
            }
        }