예제 #1
0
        private async Task RunReaderAsync()
        {
            try
            {
                if (IsServer)
                {
                    EnsureBuffer(ClientPreface.Length);
                    await ClientPreface.ReadAsync(inputStream, config.ClientPrefaceTimeout);
                }

                var continueRead = true;

                if (serverUpgradeRequest != null)
                {
                    var upgrade = serverUpgradeRequest;
                    serverUpgradeRequest = null;

                    var headers = new CompleteHeadersFrameData
                    {
                        StreamId    = 1u,
                        Priority    = null,
                        Headers     = upgrade.Headers,
                        EndOfStream = upgrade.Payload == null,
                    };

                    var err = await HandleHeaders(headers);

                    if (err != null)
                    {
                        if (err.Value.StreamId == 0)
                        {
                            continueRead = false;
                        }
                        await HandleFrameProcessingError(err.Value);
                    }
                    else if (upgrade.Payload != null)
                    {
                        var buf = config.BufferPool.Rent(upgrade.Payload.Length);
                        Array.Copy(
                            upgrade.Payload, 0, buf, 0, upgrade.Payload.Length);

                        StreamImpl stream = null;
                        lock (shared.Mutex)
                        {
                            shared.streamMap.TryGetValue(1u, out stream);
                        }

                        bool tookBufferOwnership;
                        err = stream.PushBuffer(
                            new ArraySegment <byte>(buf, 0, upgrade.Payload.Length),
                            true,
                            out tookBufferOwnership);
                        if (!tookBufferOwnership)
                        {
                            config.BufferPool.Return(buf);
                        }
                        if (err != null)
                        {
                            if (err.Value.StreamId == 0)
                            {
                                continueRead = false;
                            }
                            await HandleFrameProcessingError(err.Value);
                        }
                    }
                }

                while (continueRead)
                {
                    EnsureBuffer(PersistentBufferSize);
                    var err = await ReadOneFrame();

                    ReleaseBuffer(PersistentBufferSize);
                    if (err != null)
                    {
                        if (err.Value.StreamId == 0)
                        {
                            continueRead = false;
                        }
                        await HandleFrameProcessingError(err.Value);
                    }
                }
            }
            catch (Exception e)
            {
            }

            await writer.CloseNow();

            await writer.Done;

            Dictionary <uint, StreamImpl> activeStreams = null;

            lock (shared.Mutex)
            {
                activeStreams    = shared.streamMap;
                shared.streamMap = null;


                shared.Closed = true;
            }
            foreach (var kvp in activeStreams)
            {
                await kvp.Value.Reset(ErrorCode.ConnectError, fromRemote : true);
            }

            PingState pingState = null;

            lock (shared.Mutex)
            {
                if (shared.PingState != null)
                {
                    pingState        = shared.PingState;
                    shared.PingState = null;
                }
            }
            if (pingState != null)
            {
                var ex = new ConnectionClosedException();
                foreach (var kvp in pingState.PingMap)
                {
                    kvp.Value.SetException(ex);
                }
            }
            if (!remoteGoAwayTcs.Task.IsCompleted)
            {
                remoteGoAwayTcs.TrySetException(new EndOfStreamException());
            }

            if (receiveBuffer != null)
            {
                config.BufferPool.Return(receiveBuffer);
                receiveBuffer = null;
            }

            headerReader.Dispose();
        }
예제 #2
0
        private async Task RunAsync()
        {
            try
            {
                EnsureBuffer(Connection.PersistentBufferSize);


                if (!Connection.IsServer)
                {
                    await ClientPreface.WriteAsync(outStream);
                }

                await WriteSettingsAsync(Connection.localSettings);

                bool continueRun = true;
                while (continueRun)
                {
                    await this.wakeupWriter;

                    WriteRequest          writeRequest   = null;
                    ChangeSettingsRequest changeSettings = null;
                    bool doClose = false;

                    lock (shared.Mutex)
                    {
                        // 1: 应用新设置
                        // 2: 写一帧
                        // 3: 如果需要,请关闭连接
                        if (shared.ChangeSettingsRequest != null)
                        {
                            changeSettings = shared.ChangeSettingsRequest;
                            shared.ChangeSettingsRequest = null;
                        }
                        else
                        {
                            writeRequest = GetNextReadyWriteRequest();
                        }

                        if (changeSettings == null && writeRequest == null)
                        {
                            if (shared.CloseRequested)
                            {
                                doClose = true;
                            }
                            else
                            {
                                this.wakeupWriter.Reset();
                            }
                        }
                    }

                    if (changeSettings != null)
                    {
                        var err = ApplyNewSettings(
                            changeSettings.NewRemoteSettings);
                        if (err == null)
                        {
                            EnsureBuffer(Connection.PersistentBufferSize);
                            await WriteSettingsAckAsync();
                        }
                        changeSettings.Result = err;
                        changeSettings.Completed.Set();
                    }
                    else if (writeRequest != null)
                    {
                        EnsureBuffer(Connection.PersistentBufferSize);
                        await ProcessWriteRequestAsync(writeRequest);

                        ReleaseBuffer(Connection.PersistentBufferSize);
                    }
                    else if (doClose)
                    {
                        continueRun = false;
                    }
                }
            }
            catch (Exception e)
            {
                LogHelper.Error("ConnectionWriter.RunAsync", e);
            }


            await CloseNow(false);


            lock (shared.Mutex)
            {
                shared.CloseRequested = true;

                if (shared.ChangeSettingsRequest != null)
                {
                    shared.ChangeSettingsRequest.Completed.Set();
                    shared.ChangeSettingsRequest = null;
                }

                FinishAllOutstandingWritesLocked();
            }


            if (outBuf != null)
            {
                Connection.config.BufferPool.Return(outBuf);
                outBuf = null;
            }
        }