/// <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); } }
/// <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."); } }