private async void Read() { while (true) { var(success, ipcMessageContext) = await IpcMessageConverter.ReadAsync(NamedPipeServerStream, IpcConfiguration.MessageHeader, IpcConfiguration.SharedArrayPool); if (success) { var stream = new ByteListMessageStream(ipcMessageContext); if (IpcContext.PeerRegisterProvider.TryParsePeerRegisterMessage(stream, out var peerName)) { // ReSharper disable once MethodHasAsyncOverload PeerName = peerName; IpcServerService.OnPeerConnected(new PeerConnectedArgs(peerName, NamedPipeServerStream, ipcMessageContext.Ack)); SendAck(ipcMessageContext.Ack); // 不等待对方收到,因为对方也在等待 //await SendAckAsync(ipcMessageContext.Ack); break; } else if (IpcContext.AckManager.IsAckMessage(stream, out var ack)) { // 只有作为去连接对方的时候,才会收到这个消息 IpcContext.Logger.Debug($"[{nameof(IpcServerService)}] AckReceived {ack} From {PeerName}"); IpcContext.AckManager.OnAckReceived(this, new AckArgs(PeerName, ack)); } else { // 后续需要要求重发设备名 } } } while (true) { var(success, ipcMessageContext) = await IpcMessageConverter.ReadAsync(NamedPipeServerStream, IpcConfiguration.MessageHeader, IpcConfiguration.SharedArrayPool); if (success) { var stream = new ByteListMessageStream(ipcMessageContext); if (IpcContext.AckManager.IsAckMessage(stream, out var ack)) { IpcContext.Logger.Debug($"[{nameof(IpcServerService)}] AckReceived {ack} From {PeerName}"); IpcContext.AckManager.OnAckReceived(this, new AckArgs(PeerName, ack)); } else { SendAck(ack); IpcServerService.OnMessageReceived(new PeerMessageArgs(PeerName, stream, ack)); } } } }
public async Task RunAsync() { while (!_isDisposed) { try { var ipcMessageResult = await IpcMessageConverter.ReadAsync(Stream, IpcConfiguration.MessageHeader, IpcConfiguration.SharedArrayPool); DispatchMessage(ipcMessageResult); } catch (EndOfStreamException) { // 对方关闭了 // [断开某个进程 使用大量CPU在读取 · Issue #15 · dotnet-campus/dotnetCampus.Ipc](https://github.com/dotnet-campus/dotnetCampus.Ipc/issues/15 ) IpcContext.Logger.Error($"对方已关闭"); OnPeerConnectBroke(new PeerConnectionBrokenArgs()); return; } catch (Exception e) { IpcContext.Logger.Error(e); } } }
//public Task WriteStringAsync(string text) //{ // var buffer = Encoding.UTF8.GetBytes(text); // return WriteMessageAsync(buffer, 0, buffer.Length); //} internal async Task WriteMessageAsync(IpcBufferMessageContext ipcBufferMessageContext) { await QueueWriteAsync(async ack => { await IpcMessageConverter.WriteAsync(NamedPipeClientStream, IpcConfiguration.MessageHeader, ack, ipcBufferMessageContext, IpcContext.Logger); await NamedPipeClientStream.FlushAsync(); }); }
private async Task ReadMessageAsync() { while (!_isDisposed) { try { var ipcMessageResult = await IpcMessageConverter.ReadAsync(Stream, IpcConfiguration.MessageHeader, IpcConfiguration.SharedArrayPool); var success = ipcMessageResult.Success; var ipcMessageContext = ipcMessageResult.IpcMessageContext; var ipcMessageCommandType = ipcMessageResult.IpcMessageCommandType; if (success) { var stream = new ByteListMessageStream(ipcMessageContext); if (ipcMessageCommandType.HasFlag(IpcMessageCommandType.SendAck) && IpcContext.AckManager.IsAckMessage(stream, out var ack)) { IpcContext.Logger.Debug($"[{nameof(IpcServerService)}] AckReceived {ack} From {PeerName}"); OnAckReceived(new AckArgs(PeerName, ack)); // 如果是收到 ack 回复了,那么只需要向 AckManager 注册 Debug.Assert(ipcMessageContext.Ack.Value == IpcContext.AckUsedForReply.Value); } // 只有业务的才能发给上层 else if (ipcMessageCommandType.HasFlag(IpcMessageCommandType.Business)) { ack = ipcMessageContext.Ack; OnAckRequested(ack); OnMessageReceived(new PeerMessageArgs(PeerName, stream, ack, ipcMessageCommandType)); } else { // 有不能解析的信息,后续需要告诉开发 // 依然回复一条 Ack 消息给对方,让对方不用重复发送 OnAckRequested(ipcMessageContext.Ack); } } } catch (EndOfStreamException) { // 对方关闭了 // [断开某个进程 使用大量CPU在读取 · Issue #15 · dotnet-campus/dotnetCampus.Ipc](https://github.com/dotnet-campus/dotnetCampus.Ipc/issues/15 ) IpcContext.Logger.Error($"对方已关闭"); OnPeerConnectBroke(new PeerConnectionBrokenArgs()); return; } catch (Exception e) { IpcContext.Logger.Error(e); } } }
public void BuildPeerRegisterMessage() { "使用发送端之后,能序列化之前的字符串".Test(async() => { var peerRegisterProvider = new PeerRegisterProvider(); var pipeName = "123"; var bufferMessageContext = peerRegisterProvider.BuildPeerRegisterMessage(pipeName); var memoryStream = new MemoryStream(bufferMessageContext.Length); var ipcConfiguration = new IpcConfiguration(); await IpcMessageConverter.WriteAsync(memoryStream, ipcConfiguration.MessageHeader, 10, bufferMessageContext, null !); memoryStream.Position = 0; var(success, ipcMessageContext) = await IpcMessageConverter.ReadAsync(memoryStream, ipcConfiguration.MessageHeader, new SharedArrayPool()); Assert.AreEqual(true, success); var stream = new ByteListMessageStream(ipcMessageContext); success = peerRegisterProvider.TryParsePeerRegisterMessage(stream, out var peerName); Assert.AreEqual(true, success); Assert.AreEqual(pipeName, peerName); }); "创建的注册服务器名内容可以序列化,序列化之后可以反序列化出服务器名".Test(() => { // 创建的内容可以序列化 var peerRegisterProvider = new PeerRegisterProvider(); var pipeName = "123"; var bufferMessageContext = peerRegisterProvider.BuildPeerRegisterMessage(pipeName); var memoryStream = new MemoryStream(bufferMessageContext.Length); foreach (var ipcBufferMessage in bufferMessageContext.IpcBufferMessageList) { memoryStream.Write(ipcBufferMessage.Buffer, ipcBufferMessage.Start, ipcBufferMessage.Count); } memoryStream.Position = 0; var success = peerRegisterProvider.TryParsePeerRegisterMessage(memoryStream, out var peerName); Assert.AreEqual(true, success); Assert.AreEqual(pipeName, peerName); }); }
/// <summary> /// 向服务端发送消息 /// </summary> /// <remarks> /// 框架层使用的 /// </remarks> internal async Task WriteMessageAsync(IpcBufferMessageContext ipcBufferMessageContext) { await DoubleBufferTask.AddTaskAsync(WriteMessageAsyncInner); async Task WriteMessageAsyncInner() { await IpcMessageConverter.WriteAsync ( NamedPipeClientStream, IpcConfiguration.MessageHeader, AckManager.GetAck(), ipcBufferMessageContext, Logger ); await NamedPipeClientStream.FlushAsync(); } }
//internal async Task WriteMessageAsync(IpcBufferMessage ipcBufferMessage) //{ // await QueueWriteAsync(async ack => // { // await IpcMessageConverter.WriteAsync(NamedPipeClientStream, IpcConfiguration.MessageHeader, ack, // ipcBufferMessage); // await NamedPipeClientStream.FlushAsync(); // }); //} public async Task WriteMessageAsync(byte[] buffer, int offset, int count, [CallerMemberName] string summary = null !) { await QueueWriteAsync(async ack => { await IpcMessageConverter.WriteAsync ( NamedPipeClientStream, IpcConfiguration.MessageHeader, ack, buffer, offset, count, summary, Logger ); await NamedPipeClientStream.FlushAsync(); }); }
public void IpcMessageConverterWriteAsync() { "写入的数据和读取的相同,可以读取到写入的数据".Test(async() => { // 写入的数据和读取的相同 using var memoryStream = new MemoryStream(); var ipcConfiguration = new IpcConfiguration(); ulong ack = 10; var buffer = new byte[] { 0x12, 0x12, 0x00 }; await IpcMessageConverter.WriteAsync(memoryStream, ipcConfiguration.MessageHeader, ack, buffer, 0, buffer.Length, "test", null !); memoryStream.Position = 0; var(success, ipcMessageContext) = await IpcMessageConverter.ReadAsync(memoryStream, ipcConfiguration.MessageHeader, new SharedArrayPool()); Assert.AreEqual(true, success); Assert.AreEqual(ack, ipcMessageContext.Ack.Value); }); }
/// <summary> /// 向服务端发送消息 /// </summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="count"></param> /// <param name="summary">这一次写入的是什么内容,用于调试</param> /// <returns></returns> /// <remarks> /// 业务层使用的 /// </remarks> public async Task WriteMessageAsync(byte[] buffer, int offset, int count, [CallerMemberName] string summary = null !) { await DoubleBufferTask.AddTaskAsync(WriteMessageAsyncInner); async Task WriteMessageAsyncInner() { await IpcMessageConverter.WriteAsync ( NamedPipeClientStream, IpcConfiguration.MessageHeader, AckManager.GetAck(), // 表示这是业务层的消息 IpcMessageCommandType.Business, buffer, offset, count, summary, Logger ); await NamedPipeClientStream.FlushAsync(); } }
private async Task WaitForConnectionAsync() { while (!_isDisposed) { try { var ipcMessageResult = await IpcMessageConverter.ReadAsync(Stream, IpcConfiguration.MessageHeader, IpcConfiguration.SharedArrayPool).ConfigureAwait(false); var success = ipcMessageResult.Success; var ipcMessageContext = ipcMessageResult.IpcMessageContext; // 这不是业务消息 Debug.Assert(!ipcMessageResult.IpcMessageCommandType.HasFlag(IpcMessageCommandType.Business)); if (success) { var stream = new ByteListMessageStream(ipcMessageContext); var isPeerRegisterMessage = IpcContext.PeerRegisterProvider.TryParsePeerRegisterMessage(stream, out var peerName); if (isPeerRegisterMessage) { // ReSharper disable once MethodHasAsyncOverload PeerName = peerName; OnPeerConnected(new IpcInternalPeerConnectedArgs(peerName, Stream, ipcMessageContext.Ack, this)); //SendAckAndRegisterToPeer(ipcMessageContext.Ack); //SendAck(ipcMessageContext.Ack); //// 不等待对方收到,因为对方也在等待 ////await SendAckAsync(ipcMessageContext.Ack); } // 如果是 对方的注册消息 同时也许是回应的消息,所以不能加上 else if 判断 if (IpcContext.AckManager.IsAckMessage(stream, out var ack)) { // 只有作为去连接对方的时候,才会收到这个消息 IpcContext.Logger.Debug($"[{nameof(IpcServerService)}] AckReceived {ack} From {PeerName} 收到SendAckAndRegisterToPeer消息"); OnAckReceived(new AckArgs(PeerName, ack)); if (isPeerRegisterMessage) { // 这是一条本地主动去连接对方,然后收到对方的反过来的连接的信息,此时需要回复对方 // 参阅 SendAckAndRegisterToPeer 方法的实现 //SendAck(ipcMessageContext.Ack); OnAckRequested(ipcMessageContext.Ack); } } else { // 后续需要要求重发设备名 } if (isPeerRegisterMessage) { // 收到注册消息了 break; } } } catch (EndOfStreamException) { // 对方关闭了 // [断开某个进程 使用大量CPU在读取 · Issue #15 · dotnet-campus/dotnetCampus.Ipc](https://github.com/dotnet-campus/dotnetCampus.Ipc/issues/15 ) IpcContext.Logger.Error($"对方已关闭"); return; } catch (Exception e) { IpcContext.Logger.Error(e); } } }