Exemplo n.º 1
0
		internal void RegisterChannel(PipeServiceClientChannel channel)
		{
			lock (this.listChannels)
			{
				if (channel != null && !this.listChannels.Contains(channel))
				{
					this.listChannels.Add(channel);

					this.channels = this.listChannels.ToArray();
				}
			}
		}
Exemplo n.º 2
0
		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;
		}
Exemplo n.º 3
0
		/// <summary>
		/// 使用指定的配置文件名称、配置文件物理路径初始化 <see cref="ClientChannelEventArgs"/> 类的新实例。
		/// </summary>
		/// <param name="channel">事件相关的客户端。</param>
		public ClientChannelEventArgs(PipeServiceClientChannel channel)
		{
			this.channel = channel;
		}
Exemplo n.º 4
0
		public CallbackState(PipeServiceClientChannel channel, SendOrPostCallback callback)
		{
			this.channel = channel;
			this.lengthBuffer = new byte[4];
			this.callback = callback;
		}
Exemplo n.º 5
0
		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;
			}
		}
Exemplo n.º 6
0
		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);
		}