示例#1
0
 /// <summary>
 ///   基于命名管道通信方式的终端地址节点
 /// </summary>
 /// <param name="uri">基于命名管道形式的终端地址表现形式</param>
 /// <param name="numInstance">
 ///     当前命名管道实例数的index
 ///     <para>* index从0开始算起</para>
 /// </param>
 /// <exception cref="ArgumentNullException">参数不能为空</exception>
 /// <exception cref="UriFormatException">非法的终端地址格式</exception>
 public NamedPipeEndPoint(PipeUri uri, int numInstance)
 {
     if (uri == null)
     {
         throw new ArgumentNullException(nameof(uri));
     }
     byte[] source = _md5.ComputeHash(Encoding.UTF8.GetBytes(string.Format("{0}#{1}", uri, numInstance)));
     unsafe
     {
         fixed(byte *pData = source) _id = *(ulong *)(pData + 4);
     }
 }
示例#2
0
        /// <summary>
        /// Start listening as a server
        /// </summary>
        public void Listen(int listenBacklog = -1)
        {
            if (this.pipeNameHolder != null)
            {
                throw new InvalidOperationException("Server is already running");
            }

            this.pipeNameHolder = PipeUri.CreatePipeName(this.serverUri);
            this.listenerCts    = new CancellationTokenSource();
            var cancellationToken = this.listenerCts.Token;

            Task.Run(() => this.ListenForConnectionsAsync(listenBacklog, cancellationToken)).Forget();

            this.OnStarted();
        }
        protected override async Task <IDuplexPipe> ConnectPipelineAsync(int sendMaxMessageSize, int receiveMaxMessageSize, CancellationToken cancellationToken)
        {
            // TODO: The URL should be parsed in RpConnectionInfo constructor .
            // If invalid an ArgumentException should be thrown there.

            if (this.ConnectionInfo.HostUrl is Uri url)
            {
#pragma warning disable CA2000 // Dispose objects before losing scope
                string pipeName = PipeUri.LookupPipeName(url);
                if (string.IsNullOrEmpty(pipeName))
                {
                    throw new RpcCommunicationException(RpcCommunicationStatus.Unavailable, $"Failed to connect to named pipe at '{url}'");
                }

                NamedPipeClientStream?pipeClientStream = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, System.IO.Pipes.PipeOptions.Asynchronous);

                try
                {
                    await pipeClientStream.ConnectAsync(cancellationToken).ContextFree();

                    var sendOptions = new System.IO.Pipelines.PipeOptions(
                        pauseWriterThreshold: sendMaxMessageSize * 2, resumeWriterThreshold: sendMaxMessageSize,
                        readerScheduler: System.IO.Pipelines.PipeScheduler.Inline,
                        useSynchronizationContext: false);
                    var receiveOptions = new System.IO.Pipelines.PipeOptions(
                        pauseWriterThreshold: receiveMaxMessageSize * 2, resumeWriterThreshold: receiveMaxMessageSize,
                        readerScheduler: System.IO.Pipelines.PipeScheduler.Inline,
                        useSynchronizationContext: false);

                    var connection = new StreamDuplexPipe(pipeClientStream); //, sendOptions, receiveOptions);

                    pipeClientStream = null;                                 // Prevent disposal

                    return(connection);
                }
                finally
                {
                    pipeClientStream?.Dispose();
                }
#pragma warning restore CA2000 // Dispose objects before losing scope
            }
            else
            {
                throw new InvalidOperationException("Missing connection URL.");
            }
        }