Exemple #1
0
        private void ReadLoop()
        {
            if (!Reading)
            {
                return;
            }

            var _buffer = new byte[1024];
            var _signal = new EventSignal <CallbackDetail <int> >();

            _signal.Finished += (sender, e) =>
            {
                if (e.Result.IsFaulted)
                {
                    Exception exception = e.Result.Exception.GetBaseException();

                    if (!HttpBasedTransport.IsRequestAborted(exception))
                    {
                        if (!(exception is IOException))
                        {
                            m_connection.OnError(exception);
                        }
                        StopReading(true);
                    }
                    return;
                }

                int _read = e.Result.Result;

                if (_read > 0)
                {
                    // Put chunks in the buffer
                    m_buffer.Add(_buffer, _read);
                }

                if (_read == 0)
                {
                    // Stop any reading we're doing
                    StopReading(true);
                    return;
                }

                // Keep reading the next set of data
                ReadLoop();

                if (_read <= _buffer.Length)
                {
                    // If we read less than we wanted or if we filled the buffer, process it
                    ProcessBuffer();
                }
            };
            StreamExtensions.ReadAsync(_signal, m_stream, _buffer);
        }
 public EventSignal <NegotiationResponse> Negotiate(IConnection connection)
 {
     return(HttpBasedTransport.GetNegotiationResponse(m_httpClient, connection));
 }
Exemple #3
0
        private void OpenConnection(IConnection connection,
                                    string data,
                                    Action initializeCallback,
                                    Action <Exception> errorCallback)
        {
            // If we're reconnecting add /connect to the url
            bool                    _reconnecting   = initializeCallback == null;
            string                  _url            = (_reconnecting ? connection.Url : connection.Url + "connect");
            Action <IRequest>       _prepareRequest = PrepareRequest(connection);
            EventSignal <IResponse> _signal;

            if (shouldUsePost(connection))
            {
                _url += GetReceiveQueryString(connection, data);
                Debug.WriteLine(string.Format("SSE: POST {0}", _url));

                _signal = m_httpClient.PostAsync(
                    _url,
                    request =>
                {
                    _prepareRequest(request);
                    request.Accept = "text/event-stream";
                },
                    new Dictionary <string, string> {
                    {
                        "groups", GetSerializedGroups(connection)
                    }
                });
            }
            else
            {
                _url += GetReceiveQueryStringWithGroups(connection, data);
                Debug.WriteLine(string.Format("SSE: GET {0}", _url));

                _signal = m_httpClient.GetAsync(
                    _url,
                    request =>
                {
                    _prepareRequest(request);
                    request.Accept = "text/event-stream";
                });
            }

            _signal.Finished += (sender, e) =>
            {
                if (e.Result.IsFaulted)
                {
                    Exception _exception = e.Result.Exception.GetBaseException();

                    if (!HttpBasedTransport.IsRequestAborted(_exception))
                    {
                        if (errorCallback != null &&
                            Interlocked.Exchange(ref m_initializedCalled, 1) == 0)
                        {
                            errorCallback(_exception);
                        }
                        else if (_reconnecting)
                        {
                            // Only raise the error event if we failed to reconnect
                            connection.OnError(_exception);
                        }
                    }

                    if (_reconnecting)
                    {
                        // Retry
                        Reconnect(connection, data);
                        return;
                    }
                }
                else
                {
                    // Get the reseponse stream and read it for messages
                    IResponse         _response = e.Result;
                    Stream            _stream   = _response.GetResponseStream();
                    AsyncStreamReader _reader   = new AsyncStreamReader(
                        _stream,
                        connection,
                        () =>
                    {
                        if (Interlocked.CompareExchange(ref m_initializedCalled, 1, 0) == 0)
                        {
                            initializeCallback();
                        }
                    },
                        () =>
                    {
                        _response.Close();
                        Reconnect(connection, data);
                    });

                    if (_reconnecting)
                    {
                        // Raise the reconnect event if the connection comes back up
                        connection.OnReconnected();
                    }

                    _reader.StartReading();

                    // Set the reader for this connection
                    connection.Items[m_readerKey] = _reader;
                }
            };

            if (initializeCallback != null)
            {
                int _tryed = 0;
                while (true)
                {
                    _tryed++;
                    Debug.Write("Checking if connection initialized for the '" + _tryed.ToString() + "' time: ");

                    Thread.Sleep(m_connectionTimeout);
                    if (Interlocked.CompareExchange(ref m_initializedCalled, 1, 0) == 0)
                    {
                        if (_tryed < m_connectionRetry)
                        {
                            Debug.WriteLine("failed.");
                            continue;
                        }

                        Debug.WriteLine("giving up.");

                        // Stop the connection
                        Stop(connection);

                        // Connection timeout occurred
                        errorCallback(new TimeoutException());

                        break;
                    }
                    else
                    {
                        Debug.WriteLine("success.");
                        break;
                    }
                }
            }
        }
Exemple #4
0
        private void ProcessChunks()
        {
            //Debug.WriteLine("AsyncStreamReader: ProcessChunks");
            while (Reading && m_buffer.HasChunks)
            {
                string _line = m_buffer.ReadLine();

                // No new lines in the buffer so stop processing
                if (_line == null)
                {
                    break;
                }

                if (!Reading)
                {
                    return;
                }

                // Try parsing the sseEvent
                SseEvent _sseEvent;
                if (!SseEvent.TryParse(_line, out _sseEvent))
                {
                    continue;
                }

                if (!Reading)
                {
                    return;
                }

                //Debug.WriteLine("AsyncStreamReader: SSE READ [{0}]", _sseEvent.ToString());

                switch (_sseEvent.Type)
                {
                case EventType.Id:
                    m_connection.MessageId = _sseEvent.Data;
                    break;

                case EventType.Data:
                    if (_sseEvent.Data.Equals("initialized", StringComparison.OrdinalIgnoreCase))
                    {
                        if (m_initializeCallback != null)
                        {
                            // Mark the connection as started
                            m_initializeCallback();
                        }
                    }
                    else
                    {
                        if (Reading)
                        {
                            // We don't care about timeout messages here since it will just reconnect
                            // as part of being a long running request
                            bool _timedOutReceived;
                            bool _disconnectReceived;

                            HttpBasedTransport.ProcessResponse(
                                m_connection,
                                _sseEvent.Data,
                                out _timedOutReceived,
                                out _disconnectReceived);

                            if (_disconnectReceived)
                            {
                                m_connection.Stop();
                            }

                            if (_timedOutReceived)
                            {
                                return;
                            }
                        }
                    }
                    break;
                }
            }
        }