示例#1
0
        private void BeginSend(TcpKsiServiceAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                return;
            }

            try
            {
                if (!_waitSocketConnectHandle.WaitOne(_requestTimeOut))
                {
                    Logger.Debug("Request timed out. Waiting _waitSocketConnectHandle in BeginSend timed out.");
                    throw new KsiServiceProtocolException("Request timed out.");
                }

                Logger.Debug("Starting sending (request id: {0}).", asyncResult.RequestId);

                if (!asyncResult.IsCompleted)
                {
                    if (_socket == null)
                    {
                        // stop sending if socket is closed meanwhile
                        Logger.Debug("Stopping sending. No socket. (request id: {0}).", asyncResult.RequestId);
                    }
                    else
                    {
                        _socket.BeginSend(asyncResult.PostData, 0, asyncResult.PostData.Length, 0, SendCallback, asyncResult);
                    }
                }
            }
            catch (Exception e)
            {
                SetError(asyncResult, e, "Failed to start sending.");
            }
        }
示例#2
0
 /// <summary>
 /// Add new async result into the collection
 /// </summary>
 /// <param name="key">The key of the element to add</param>
 /// <param name="asyncResult">Asycn result to add</param>
 public void Add(ulong key, TcpKsiServiceAsyncResult asyncResult)
 {
     lock (_syncObj)
     {
         _list.Add(key, asyncResult);
     }
 }
示例#3
0
        private void SetError(Exception e, string errorMessage)
        {
            // Wait until making a new request, retrying or disposing is in progress
            lock (_syncObject)
            {
                try
                {
                    Logger.Debug(errorMessage + Environment.NewLine + e + Environment.NewLine + "Closing socket due to error.");
                    CloseSocket();

                    // no specific asyncResult, notify all pending requests about the error
                    foreach (ulong key in _asyncResults.GetKeys())
                    {
                        TcpKsiServiceAsyncResult asyncResult = _asyncResults.GetValue(key);
                        // If an error already exists then do not overwrite.
                        if (asyncResult.Error != null)
                        {
                            continue;
                        }
                        asyncResult.Error = new KsiServiceProtocolException(errorMessage, e);
                        asyncResult.SetComplete();
                    }

                    Logger.Debug("Clearing asyncResults.");
                    _asyncResults.Clear();
                }
                catch (Exception ex)
                {
                    Logger.Debug("SetError failed.", ex);
                    throw;
                }
            }
        }
示例#4
0
 /// <summary>
 /// Remove async result from the collection
 /// </summary>
 /// <param name="asyncResult">Async result to removed</param>
 public void Remove(TcpKsiServiceAsyncResult asyncResult)
 {
     lock (_syncObj)
     {
         if (_list.ContainsKey(asyncResult.RequestId))
         {
             _list.Remove(asyncResult.RequestId);
         }
     }
 }
示例#5
0
        /// <summary>
        /// End TCP request
        /// </summary>
        /// <param name="ar">TCP KSI service async result</param>
        /// <returns></returns>
        protected byte[] EndRequest(IAsyncResult ar)
        {
            TcpKsiServiceAsyncResult asyncResult = ar as TcpKsiServiceAsyncResult;

            if (asyncResult == null)
            {
                throw new KsiServiceProtocolException("Invalid IAsyncResult.");
            }

            try
            {
                if (_isDisposed)
                {
                    throw new KsiServiceProtocolException("TCP KSI service protocol is disposed.");
                }

                if (asyncResult.IsDisposed)
                {
                    throw new KsiServiceProtocolException("Provided async result is already disposed. Possibly using the same async result twice when ending request.");
                }

                if (!asyncResult.IsCompleted)
                {
                    if (!asyncResult.AsyncWaitHandle.WaitOne(_requestTimeOut))
                    {
                        Logger.Debug("Request timed out. Waiting asyncResult.AsyncWaitHandle in EndRequest timed out.");
                        throw new KsiServiceProtocolException("Request timed out.");
                    }
                }

                if (asyncResult.HasError)
                {
                    Logger.Warn("{0} (request id: {1}){2}{3}", asyncResult.Error.Message, asyncResult.RequestId, Environment.NewLine, asyncResult.Error);
                    throw asyncResult.Error;
                }

                Logger.Debug("TCP service protocol returning {0} bytes (request id: {1}).", asyncResult.ResultStream.Length, asyncResult.RequestId);

                return(asyncResult.ResultStream.ToArray());
            }
            finally
            {
                asyncResult.Dispose();
            }
        }
示例#6
0
 private void SetError(TcpKsiServiceAsyncResult asyncResult, Exception e, string errorMessage)
 {
     try
     {
         // If an error already exists then do not overwrite.
         if (asyncResult.Error != null)
         {
             return;
         }
         asyncResult.Error = new KsiServiceProtocolException(errorMessage, e);
         asyncResult.SetComplete();
         _asyncResults.Remove(asyncResult);
     }
     catch (Exception ex)
     {
         Logger.Debug("SetError with asyncResult failed.", ex);
         throw;
     }
 }
示例#7
0
        private void SendCallback(IAsyncResult ar)
        {
            TcpKsiServiceAsyncResult asyncResult = (TcpKsiServiceAsyncResult)ar.AsyncState;

            if (asyncResult.IsCompleted)
            {
                return;
            }

            try
            {
                int bytesSent = _socket.EndSend(ar);
                Logger.Debug("{0} bytes sent to server (request id: {1}).", bytesSent, asyncResult.RequestId);
            }
            catch (Exception e)
            {
                SetError(asyncResult, e, "Failed to complete sending.");
            }
        }
示例#8
0
        private void EndBeginRequestCallback(object state, bool timedOut)
        {
            try
            {
                TcpKsiServiceAsyncResult asyncResult = (TcpKsiServiceAsyncResult)state;
                _asyncResults.Remove(asyncResult);

                if (timedOut)
                {
                    asyncResult.Error = new KsiServiceProtocolException("Request timed out.");
                }

                asyncResult.SetComplete();
            }
            catch (Exception ex)
            {
                Logger.Debug("EndBeginRequestCallback failed.", ex);
                throw;
            }
        }
示例#9
0
        /// <summary>
        /// Begin TCP request
        /// </summary>
        /// <param name="requestType"></param>
        /// <param name="data">request bytes</param>
        /// <param name="requestId">request id</param>
        /// <param name="callback">callback when request is finished</param>
        /// <param name="asyncState">async state object</param>
        /// <returns></returns>
        protected IAsyncResult BeginRequest(KsiServiceRequestType requestType, byte[] data, ulong requestId, AsyncCallback callback, object asyncState)
        {
            if (_isDisposed)
            {
                throw new KsiServiceProtocolException("TCP KSI service protocol is disposed.");
            }

            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            TcpKsiServiceAsyncResult asyncResult = new TcpKsiServiceAsyncResult(requestType, data, requestId, callback, asyncState);

            Logger.Debug("Begin TCP request (request id: {0}).", asyncResult.RequestId);

            // Wait until retrying, disposing or error throwing is in progress
            lock (_syncObject)
            {
                _asyncResults.Add(requestId, asyncResult);
            }

            if (_socket == null)
            {
                CreateSocketAndConnect();
            }

            // Before starting sending request check that other request (possibly failed) haven't finished and disposed the async result.
            if (!asyncResult.IsDisposed)
            {
                ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, EndBeginRequestCallback, asyncResult, _requestTimeOut, true);

                BeginSend(asyncResult);
            }

            return(asyncResult);
        }
        /// <summary>
        /// Returns asyncResults according to response payload.
        /// If aggregation response payload then return asyncResult by request id.
        /// If error payload then return all asyncResults.
        /// If config response payload the return all asyncResults created by config requests.
        /// </summary>
        /// <param name="payloadInfo">Response payload info</param>
        /// <returns></returns>
        private List <TcpKsiServiceAsyncResult> GetAsyncResults(KsiServiceResponsePayloadInfo payloadInfo)
        {
            List <TcpKsiServiceAsyncResult> list = new List <TcpKsiServiceAsyncResult>();

            ulong[] keys = _asyncResults.GetKeys();

            switch (payloadInfo.ResponsePayloadType)
            {
            case KsiServiceResponsePayloadType.Aggregation:
            case KsiServiceResponsePayloadType.Extending:
                foreach (ulong key in keys)
                {
                    if (key == payloadInfo.RequestId)
                    {
                        TcpKsiServiceAsyncResult asyncResult = _asyncResults.GetValue(key);

                        if (asyncResult == null)
                        {
                            continue;
                        }

                        list.Add(asyncResult);
                    }
                }
                break;

            case KsiServiceResponsePayloadType.AggregatorConfig:
                // return all async results of all aggregator configuration requests
                foreach (ulong key in keys)
                {
                    TcpKsiServiceAsyncResult asyncResult = _asyncResults.GetValue(key);

                    if (asyncResult?.ServiceRequestType == KsiServiceRequestType.AggregatorConfig)
                    {
                        list.Add(asyncResult);
                    }
                }
                break;

            case KsiServiceResponsePayloadType.ExtenderConfig:
                // return all async results of all extender configuration requests
                foreach (ulong key in keys)
                {
                    TcpKsiServiceAsyncResult asyncResult = _asyncResults.GetValue(key);

                    if (asyncResult?.ServiceRequestType == KsiServiceRequestType.ExtenderConfig)
                    {
                        list.Add(asyncResult);
                    }
                }
                break;

            case KsiServiceResponsePayloadType.Error:
                foreach (ulong key in keys)
                {
                    TcpKsiServiceAsyncResult asyncResult = _asyncResults.GetValue(key);

                    if (asyncResult != null)
                    {
                        list.Add(asyncResult);
                    }
                }
                break;

            default:
                throw new KsiServiceProtocolException("Unhandled payload type.");
            }

            return(list);
        }