Exemple #1
0
 /// <summary>
 /// 连接至服务器。
 /// </summary>
 /// <param name="endpoint">服务器终结点。</param>
 public void Connect(IPEndPoint endpoint)
 {
     //判断是否已连接
     if (IsConnected)
     {
         throw new InvalidOperationException("已连接至服务器。");
     }
     if (endpoint == null)
     {
         throw new ArgumentNullException("endpoint");
     }
     //锁定自己,避免多线程同时操作
     lock (this)
     {
         SocketAsyncState state = new SocketAsyncState();
         //Socket异步连接
         Socket.BeginConnect(endpoint, EndConnect, state).AsyncWaitHandle.WaitOne();
         //等待异步全部处理完成
         while (!state.Completed)
         {
             Thread.Sleep(1);
         }
     }
 }
        private static Exception ThrowException(SocketAsyncState state)
        {
            var statusName = Enum.GetName(typeof(ResponseStatus), state.Status);

            switch (state.Status)
            {
            case ResponseStatus.KeyNotFound:
                return(new KeyNotFoundException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.KeyExists:
                return(new KeyExistsException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.ValueTooLarge:
                return(new ValueTooLargeException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.InvalidArguments:
                return(new InvalidArgumentException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.TemporaryFailure:
            case ResponseStatus.OutOfMemory:
            case ResponseStatus.Busy:
                return(new TempFailException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.OperationTimeout:
                return(new TimeoutException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.Locked:
                return(new KeyLockedException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.DocumentMutationLost:
            case ResponseStatus.DocumentMutationDetected:
            case ResponseStatus.NoReplicasFound:
            case ResponseStatus.DurabilityInvalidLevel:
            case ResponseStatus.DurabilityImpossible:
            case ResponseStatus.SyncWriteInProgress:
            case ResponseStatus.SyncWriteAmbiguous:
                return(new DurabilityException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.Eaccess:
            case ResponseStatus.AuthenticationError:
                return(new AuthenticationException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            //internal errors handled by the app?
            case ResponseStatus.Rollback:
            case ResponseStatus.VBucketBelongsToAnotherServer:
            case ResponseStatus.AuthenticationContinue:
            case ResponseStatus.AuthStale:
            case ResponseStatus.InternalError:
            case ResponseStatus.UnknownCommand:
            case ResponseStatus.BucketNotConnected:
            case ResponseStatus.UnknownError:
            case ResponseStatus.NotInitialized:
            case ResponseStatus.NotSupported:
            case ResponseStatus.SubdocXattrUnknownVattr:
            case ResponseStatus.SubDocMultiPathFailure:
            case ResponseStatus.SubDocXattrInvalidFlagCombo:
            case ResponseStatus.SubDocXattrInvalidKeyCombo:
            case ResponseStatus.SubdocXattrCantModifyVattr:
            case ResponseStatus.SubdocMultiPathFailureDeleted:
            case ResponseStatus.SubdocInvalidXattrOrder:
                return(new InternalErrorException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.InvalidRange:
            case ResponseStatus.ItemNotStored:
            case ResponseStatus.IncrDecrOnNonNumericValue:
                return(new KeyValueException     //hmm?
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                });

            //sub doc errors
            case ResponseStatus.SubDocPathNotFound:
                return(new PathNotFoundException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.SubDocPathMismatch:
                return(new PathMismatchException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.SubDocPathInvalid:
                return(new PathInvalidException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.SubDocPathTooBig:
                return(new PathTooBigException(statusName, new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                }));

            case ResponseStatus.SubDocDocTooDeep:
            case ResponseStatus.SubDocCannotInsert:
            case ResponseStatus.SubDocDocNotJson:
            case ResponseStatus.SubDocNumRange:
            case ResponseStatus.SubDocDeltaRange:
            case ResponseStatus.SubDocPathExists:
            case ResponseStatus.SubDocValueTooDeep:
            case ResponseStatus.SubDocInvalidCombo:
            case ResponseStatus.SubdocXattrUnknownMacro:
                return(new KeyValueException
                {
                    Status = state.Status,
                    ErrorMap = state.ErrorMap
                });

            //remove these ones
            case ResponseStatus.Failure:
            case ResponseStatus.ClientFailure:
                break;

            case ResponseStatus.NodeUnavailable:
                break;

            case ResponseStatus.TransportFailure:
                return(state.Exception);

            default:
                return(new ArgumentOutOfRangeException());
            }
            return(new Exception("oh me oh mai..."));
        }
Exemple #3
0
        public async Task SendAsync(ReadOnlyMemory <byte> request, Func <SocketAsyncState, Task> callback, ErrorMap errorMap)
        {
            ExceptionDispatchInfo capturedException = null;
            SocketAsyncState      state             = null;

            try
            {
                var opaque = ByteConverter.ToUInt32(request.Span.Slice(HeaderOffsets.Opaque));
                state = new SocketAsyncState
                {
                    Opaque        = opaque,
                    EndPoint      = (IPEndPoint)EndPoint,
                    ConnectionId  = ConnectionId,
                    LocalEndpoint = LocalEndPoint.ToString()
                };

                if (!MemoryMarshal.TryGetArray <byte>(request, out var arraySegment))
                {
                    // Fallback in case we can't use the more efficient TryGetArray method
                    arraySegment = new ArraySegment <byte>(request.ToArray());
                }

                // write data to stream
                await _sslStream.WriteAsync(arraySegment.Array, 0, request.Length).ConfigureAwait(false);

                // wait for response
                var received = await _sslStream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length).ConfigureAwait(false);

                var responseSize = ByteConverter.ToInt32(_receiveBuffer.AsSpan(HeaderOffsets.BodyLength)) + HeaderOffsets.HeaderLength;

                // create memory slice and copy first segment
                var response = MemoryPool <byte> .Shared.RentAndSlice(responseSize);

                _receiveBuffer.AsMemory(0, received).CopyTo(response.Memory);

                // append any further segments as required
                while (received < responseSize)
                {
                    var segmentLength = await _sslStream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length).ConfigureAwait(false);

                    _receiveBuffer.AsMemory(0, segmentLength).CopyTo(response.Memory);
                    received += segmentLength;
                }

                // write response to state and complete callback
                state.SetData(response);
                await callback(state).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                IsDead            = true;
                capturedException = ExceptionDispatchInfo.Capture(e);
            }

            if (capturedException != null)
            {
                var sourceException = capturedException.SourceException;
                if (state == null)
                {
                    await callback(new SocketAsyncState
                    {
                        Exception = capturedException.SourceException,
                        Status    = (sourceException is SocketException)
                            ? ResponseStatus.TransportFailure
                            : ResponseStatus.ClientFailure
                    }).ConfigureAwait(false);
                }
                else
                {
                    state.Exception = sourceException;
                    await state.Completed(state).ConfigureAwait(false);

                    Log.LogDebug(sourceException, "");
                }
            }
        }