Пример #1
0
        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));
                    }
                }
            }
        }
Пример #2
0
        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);
                }
            }
        }
Пример #3
0
        //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();
            });
        }
Пример #4
0
        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);
                }
            }
        }
Пример #5
0
        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);
            });
        }
Пример #6
0
        /// <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();
            }
        }
Пример #7
0
        //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();
            });
        }
Пример #8
0
        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);
            });
        }
Пример #9
0
        /// <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();
            }
        }
Пример #10
0
        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);
                }
            }
        }