예제 #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
        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);
                }
            }
        }
예제 #3
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);
            });
        }
예제 #4
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);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// 调度消息
        /// </summary>
        /// <param name="ipcMessageResult"></param>
        private void DispatchMessage(IpcMessageResult ipcMessageResult)
        {
            var success               = ipcMessageResult.Success;
            var ipcMessageContext     = ipcMessageResult.IpcMessageContext;
            var ipcMessageCommandType = ipcMessageResult.IpcMessageCommandType;

            if (!success)
            {
                // 没有成功哇
                return;
            }

            var stream = new ByteListMessageStream(ipcMessageContext);

            if (ipcMessageCommandType.HasFlag(IpcMessageCommandType.PeerRegister))
            {
                var isPeerRegisterMessage =
                    IpcContext.PeerRegisterProvider.TryParsePeerRegisterMessage(stream, out var peerName);

                if (IsConnected)
                {
                    // 对方是不是挂了?居然重复注册
                    // 注册的逻辑可是框架层做的哦,业务层可决定不了
                    // 可能存在的原因是注册的时候,本进程太忙碌,于是对方连续给了两条注册消息过来,这也是预期的

                    if (string.Equals(PeerName, peerName))
                    {
                        // 也许是对方发送两条注册消息过来
                    }
                    else
                    {
                        // 对方想改名而已
                    }
                }

                if (isPeerRegisterMessage)
                {
                    PeerName = peerName;

                    OnPeerConnected(new IpcInternalPeerConnectedArgs(peerName, Stream, ipcMessageContext.Ack,
                                                                     this));

                    if (string.IsNullOrEmpty(peerName))
                    {
                        // 这难道是 lsj 的号?居然名字是空的
                    }
                }
                else
                {
                    // 版本不对?消息明明是说注册的,然而解析失败
                }
            }
            // 只有业务的才能发给上层
            else if (ipcMessageCommandType.HasFlag(IpcMessageCommandType.Business))
            {
                if (IsConnected)
                {
                    OnMessageReceived(new PeerMessageArgs(PeerName, stream, ipcMessageContext.Ack, ipcMessageCommandType));
                }
                else
                {
                    // 还没注册完成哇
                }
            }
            else
            {
                // 不知道这是啥消息哇
                // 但是更新一下 ack 意思一下还可以
                OnAckReceived(new AckArgs(PeerName, ipcMessageContext.Ack));
            }
        }
        public void BuildPeerRegisterMessage()
        {
            "如果注册消息的内容添加了其他内容,不会读取到不属于注册消息的内容".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);
                }

                // 写入其他内容
                var streamWriter = new StreamWriter(memoryStream);
                streamWriter.Write("林德熙是逗比");
                streamWriter.Flush();

                memoryStream.Position = 0;

                var success = peerRegisterProvider.TryParsePeerRegisterMessage(memoryStream, out var peerName);

                Assert.AreEqual(true, success);
                Assert.AreEqual(pipeName, peerName);
            });

            "如果消息不是对方的注册消息,那么将不修改Stream的起始".Test(() =>
            {
                var peerRegisterProvider = new PeerRegisterProvider();
                var memoryStream         = new MemoryStream();
                for (int i = 0; i < 1000; i++)
                {
                    memoryStream.WriteByte(0x00);
                }

                const int position        = 10;
                memoryStream.Position     = position;
                var isPeerRegisterMessage = peerRegisterProvider.TryParsePeerRegisterMessage(memoryStream, out _);
                Assert.AreEqual(false, isPeerRegisterMessage);
                Assert.AreEqual(position, memoryStream.Position);
            });

            "使用发送端之后,能序列化之前的字符串".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);
            });
        }