internal void RegisterChannel(PipeServiceClientChannel channel) { lock (this.listChannels) { if (channel != null && !this.listChannels.Contains(channel)) { this.listChannels.Add(channel); this.channels = this.listChannels.ToArray(); } } }
private void Listen4Connect() { IntervalLogger logger = new IntervalLogger(TimeSpan.FromMinutes(1)); NamedPipeServerStream listenPipeServerStream = null; while (this.isRunning) { try { listenPipeServerStream = new NamedPipeServerStream(this.pipeName, PipeDirection.InOut, this.owner.maxNumberOfServerInstances, PipeTransmissionMode.Message, PipeOptions.Asynchronous, this.owner.bufferSize, this.owner.bufferSize); //Console.WriteLine("等待客户端的连接"); listenPipeServerStream.WaitForConnection(); if (this.isRunning) { lock (this.syncObject) { if (this.isRunning) { TimeoutHelper timeoutHelper = this.owner.openTimeout < 0 ? new TimeoutHelper(TimeSpan.FromMilliseconds(60000)) : new TimeoutHelper(TimeSpan.FromMilliseconds(this.owner.openTimeout)); // 验证 BinarySerializeHelper.Write(this.formatter, listenPipeServerStream, this.pipeName, true, timeoutHelper); // listenPipeServerStream.WaitForPipeDrain(); string clientResponse = BinarySerializeHelper.Read(this.formatter, listenPipeServerStream, true, timeoutHelper) as string; PipeServiceClient pipeServiceClient = PipeServiceClient.Parse(clientResponse); if (pipeServiceClient == null) { listenPipeServerStream.Close(); continue; } // 针对某个连接上的客户端,其第一个连接永远不超时,直到客户端主动关闭连接为止 int receiveTimeout = -1; if (this.clients.ContainsKey(pipeServiceClient.AppInstanceId)) { // 第一个连接之外的连接,如果一段时间没有接收到数据,则关闭该连接 receiveTimeout = this.owner.receiveTimeout; pipeServiceClient = this.clients[pipeServiceClient.AppInstanceId]; } else { this.clients[pipeServiceClient.AppInstanceId] = pipeServiceClient; } PipeServiceClientChannel channel = new PipeServiceClientChannel(pipeServiceClient, this.owner.listenThreadPriority, receiveTimeout, this.owner.sendTimeout); channel.owner = this.owner; channel.pipeStream = listenPipeServerStream; pipeServiceClient.RegisterChannel(channel); channel.Closed += new ClientChannelEventHandler(channel_ChannelClosed); channel.DataReceived += new DataReceivedEventHandler(channel_DataReceived); // 引发通道连接事件 this.owner.FireClientChannelConnected(new ClientChannelEventArgs(channel)); // 当是第一个连接时引发客户端连接事件 if (pipeServiceClient.Channels.Length <= 1) { this.owner.FireClientConnected(new ClientConnectEventArgs(pipeServiceClient)); } //Console.WriteLine("开始监听客户端的请求"); channel.Open(); continue; } } } } catch (System.Threading.ThreadAbortException) { // 捕获到 ThreadAbortException 时,在执行完 catch 块里的内容后,将立即结束整个线程的执行,因此要在 catch 里做必须的资源清理和标志设定工作 this.isListenThreadStoped = true; if (listenPipeServerStream != null) { try { if (listenPipeServerStream.IsConnected) { listenPipeServerStream.Disconnect(); } listenPipeServerStream.Close(); } catch { } } } catch (Exception err) { if (listenPipeServerStream != null) { try { if (listenPipeServerStream.IsConnected) { listenPipeServerStream.Disconnect(); } listenPipeServerStream.Close(); } catch { } } logger.Warn(err, PipeConstants.LogCategory); System.Threading.Thread.Sleep(100); } finally { listenPipeServerStream = null; } } this.isListenThreadStoped = true; }
/// <summary> /// 使用指定的配置文件名称、配置文件物理路径初始化 <see cref="ClientChannelEventArgs"/> 类的新实例。 /// </summary> /// <param name="channel">事件相关的客户端。</param> public ClientChannelEventArgs(PipeServiceClientChannel channel) { this.channel = channel; }
public CallbackState(PipeServiceClientChannel channel, SendOrPostCallback callback) { this.channel = channel; this.lengthBuffer = new byte[4]; this.callback = callback; }
private static object ReadData(PipeServiceClientChannel channel, BinaryFormatter formatter, int length) { if (channel == null) { throw new ArgumentNullException("channel"); } using (MemoryStream ms = new MemoryStream(length)) { byte[] buffer = new byte[channel.pipeStream.InBufferSize]; // 当消息体较大时,对流的其余部分进行读取,这些输出以 maxBufferSize 为基准对消息体进行分块读取 // 这尽可能的减少了循环的次数,进而减少了异步调用(需要使用工作线程)的开销,最终尽可能的提升了性能 while (ms.Length < length) { int shouldReadCount = length - (int)ms.Length > buffer.Length ? buffer.Length : length - (int)ms.Length; int readCount = channel.pipeStream.Read(buffer, 0, shouldReadCount); if (readCount == 0) { // 由于管道关闭而引起的管道流已结束,这时读到的数据长度为 0,这时应抛出管道异常 throw new IOException("管道已关闭"); } // 不是预期的长度,则抛出格式化异常 else if (readCount != shouldReadCount) { throw new InvalidDataException(); } ms.Write(buffer, 0, readCount); } // 将内存流的位置设置到流的开头,以方便后续进行反序列化 ms.Seek(0, SeekOrigin.Begin); object data = formatter.Deserialize(ms); return data; } }
public static void BeginReceive(PipeServiceClientChannel channel, SendOrPostCallback callback) { CallbackState state = new CallbackState(channel, callback); state.InvokeStacks.Add(new KeyValue<DateTime, string>() { Key = DateTime.Now, Value = Thread.CurrentThread.ManagedThreadId.ToString("#000") + " " + (Thread.CurrentThread.IsThreadPoolThread ? "true" : "false") + " BeginRead: ChannelsCount=" + channel.Client.Channels.Length }); channel.pipeStream.BeginRead(state.LengthBuffer, 0, state.LengthBuffer.Length, new AsyncCallback(ReadCallback), state); }