Пример #1
0
                public cCommandPipeline(cCallbackSynchroniser pSynchroniser, Action <cTrace.cContext> pDisconnected, cBatchSizerConfiguration pNetworkWriteConfiguration, cIdleConfiguration pIdleConfiguration, cTrace.cContext pParentContext)
                {
                    var lContext = pParentContext.NewObject(nameof(cCommandPipeline), pIdleConfiguration);

                    mSynchroniser = pSynchroniser ?? throw new ArgumentNullException(nameof(pSynchroniser));
                    mDisconnected = pDisconnected ?? throw new ArgumentNullException(nameof(pDisconnected));
                    if (pNetworkWriteConfiguration == null)
                    {
                        throw new ArgumentNullException(nameof(pNetworkWriteConfiguration));
                    }
                    mConnection        = new cConnection(pNetworkWriteConfiguration);
                    mIdleConfiguration = pIdleConfiguration;

                    mResponseTextProcessor = new cResponseTextProcessor(pSynchroniser);

                    // these depend on the cancellationtokensource being constructed
                    mBackgroundReleaser = new cReleaser("commandpipeline_background", mBackgroundCancellationTokenSource.Token);
                    mBackgroundAwaiter  = new cAwaiter(mBackgroundCancellationTokenSource.Token);

                    mBackgroundSendBuffer = new cSendBuffer(pSynchroniser, mConnection, mBackgroundCancellationTokenSource.Token);

                    // plumbing
                    mIdleBlock.Released += mBackgroundReleaser.Release; // when the idle block is removed, kick the background process
                }
Пример #2
0
                public async Task <sGreeting> ConnectAsync(cMethodControl pMC, cServer pServer, cTrace.cContext pParentContext)
                {
                    var lContext = pParentContext.NewMethod(nameof(cCommandPipeline), nameof(ConnectAsync), pMC, pServer);

                    if (mDisposed)
                    {
                        throw new ObjectDisposedException(nameof(cCommandPipeline));
                    }

                    if (mState != eState.notconnected)
                    {
                        throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotUnconnected);
                    }
                    mState = eState.connecting;

                    try
                    {
                        await mConnection.ConnectAsync(pMC, pServer, lContext).ConfigureAwait(false);

                        using (var lAwaiter = new cAwaiter(pMC))
                        {
                            while (true)
                            {
                                lContext.TraceVerbose("waiting");
                                await lAwaiter.AwaitAny(mConnection.GetBuildResponseTask(lContext)).ConfigureAwait(false);

                                var lResponse = mConnection.GetResponse(lContext);
                                mSynchroniser.InvokeNetworkReceive(lResponse, lContext);
                                var lCursor = new cBytesCursor(lResponse);

                                if (lCursor.SkipBytes(kGreetingAsteriskSpaceOKSpace))
                                {
                                    var lHook = new cCommandHookInitial();

                                    cResponseText lResponseText = mResponseTextProcessor.Process(eResponseTextContext.greetingok, lCursor, lHook, lContext);
                                    lContext.TraceVerbose("got ok: {0}", lResponseText);

                                    mState          = eState.connected;
                                    mBackgroundTask = ZBackgroundTaskAsync(lContext);

                                    mCapabilities             = lHook.Capabilities;
                                    mAuthenticationMechanisms = lHook.AuthenticationMechanisms;

                                    return(new sGreeting(eGreetingType.ok, null));
                                }

                                if (lCursor.SkipBytes(kGreetingAsteriskSpacePreAuthSpace))
                                {
                                    var lHook = new cCommandHookInitial();

                                    cResponseText lResponseText = mResponseTextProcessor.Process(eResponseTextContext.greetingpreauth, lCursor, lHook, lContext);
                                    lContext.TraceVerbose("got preauth: {0}", lResponseText);

                                    mState          = eState.connected;
                                    mBackgroundTask = ZBackgroundTaskAsync(lContext);

                                    mCapabilities             = lHook.Capabilities;
                                    mAuthenticationMechanisms = lHook.AuthenticationMechanisms;

                                    return(new sGreeting(eGreetingType.preauth, lResponseText));
                                }

                                if (lCursor.SkipBytes(kGreetingAsteriskSpaceBYESpace))
                                {
                                    cResponseText lResponseText = mResponseTextProcessor.Process(eResponseTextContext.greetingbye, lCursor, null, lContext);
                                    lContext.TraceError("got bye: {0}", lResponseText);

                                    mConnection.Disconnect(lContext);

                                    mState = eState.stopped;
                                    return(new sGreeting(eGreetingType.bye, lResponseText));
                                }

                                lContext.TraceError("unrecognised response: {0}", lResponse);
                            }
                        }
                    }
                    catch (Exception)
                    {
                        mConnection.Disconnect(lContext);
                        mState = eState.stopped;
                        throw;
                    }
                }