diff --git a/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Models/GeneratedProxyMemberInvokeModel.cs b/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Models/GeneratedProxyMemberInvokeModel.cs
index 96843765..946a3689 100644
--- a/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Models/GeneratedProxyMemberInvokeModel.cs
+++ b/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Models/GeneratedProxyMemberInvokeModel.cs
@@ -1,11 +1,14 @@
-using System.Diagnostics.CodeAnalysis;
+using System;
+using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Runtime.Serialization;
using System.Text;
using dotnetCampus.Ipc.CompilerServices.GeneratedProxies.Models;
+using dotnetCampus.Ipc.Context;
using dotnetCampus.Ipc.Messages;
using dotnetCampus.Ipc.Serialization;
+using dotnetCampus.Ipc.Utils.Extensions;
namespace dotnetCampus.Ipc.CompilerServices.GeneratedProxies
{
@@ -69,7 +72,11 @@ public string Id
///
public static IpcMessage Serialize(GeneratedProxyMemberInvokeModel model)
{
- return JsonIpcMessageSerializer.Serialize(model.ToString(), model);
+ // 加上头信息
+ var serializeMessage = JsonIpcMessageSerializer.Serialize(model.ToString(), model);
+
+ return new IpcMessage(serializeMessage.Tag, serializeMessage.Body,
+ (ulong) KnownMessageHeaders.RemoteObjectMessageHeader);
}
///
@@ -80,7 +87,19 @@ public static IpcMessage Serialize(GeneratedProxyMemberInvokeModel model)
///
public static bool TryDeserialize(IpcMessage message, [NotNullWhen(true)] out GeneratedProxyMemberInvokeModel? model)
{
- return JsonIpcMessageSerializer.TryDeserialize(message, out model);
+ if (message.TryReadBusinessHeader(out var header) && header == (ulong) KnownMessageHeaders.RemoteObjectMessageHeader)
+ {
+ // 跳过业务头的消息内容
+ var deserializeMessage = message.Skip(sizeof(ulong));
+
+ return JsonIpcMessageSerializer.TryDeserialize(deserializeMessage, out model);
+ }
+ else
+ {
+ // 如果业务头不对,那就不需要解析了
+ model = null;
+ return false;
+ }
}
///
diff --git a/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Models/GeneratedProxyMemberReturnModel.cs b/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Models/GeneratedProxyMemberReturnModel.cs
index a3ada21b..d2603a99 100644
--- a/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Models/GeneratedProxyMemberReturnModel.cs
+++ b/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Models/GeneratedProxyMemberReturnModel.cs
@@ -3,8 +3,10 @@
using System.Runtime.Serialization;
using dotnetCampus.Ipc.CompilerServices.GeneratedProxies.Models;
+using dotnetCampus.Ipc.Context;
using dotnetCampus.Ipc.Messages;
using dotnetCampus.Ipc.Serialization;
+using dotnetCampus.Ipc.Utils.Extensions;
namespace dotnetCampus.Ipc.CompilerServices.GeneratedProxies
{
@@ -56,12 +58,27 @@ public GeneratedProxyMemberReturnModel(Exception exception)
public static IpcMessage Serialize(GeneratedProxyMemberReturnModel model)
{
- return JsonIpcMessageSerializer.Serialize("Return", model);
+ var serializeMessage = JsonIpcMessageSerializer.Serialize("Return", model);
+
+ return new IpcMessage(serializeMessage.Tag, serializeMessage.Body,
+ (ulong) KnownMessageHeaders.RemoteObjectMessageHeader);
}
public static bool TryDeserialize(IpcMessage message, [NotNullWhen(true)] out GeneratedProxyMemberReturnModel? model)
{
- return JsonIpcMessageSerializer.TryDeserialize(message, out model);
+ if (message.TryReadBusinessHeader(out var header) && header == (ulong) KnownMessageHeaders.RemoteObjectMessageHeader)
+ {
+ // 跳过业务头的消息内容
+ var deserializeMessage = message.Skip(sizeof(ulong));
+
+ return JsonIpcMessageSerializer.TryDeserialize(deserializeMessage, out model);
+ }
+ else
+ {
+ // 如果业务头不对,那就不需要解析了
+ model = null;
+ return false;
+ }
}
}
}
diff --git a/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Utils/IpcProxyInvokingHelper.cs b/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Utils/IpcProxyInvokingHelper.cs
index 2c479bae..1957551f 100644
--- a/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Utils/IpcProxyInvokingHelper.cs
+++ b/src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Utils/IpcProxyInvokingHelper.cs
@@ -93,7 +93,7 @@ internal string TypeName
}
var requestMessage = GeneratedProxyMemberInvokeModel.Serialize(model);
- requestMessage = new IpcMessage(requestMessage.Tag, requestMessage.Body, CoreMessageType.JsonObject);
+ //requestMessage = new IpcMessage(requestMessage.Tag, requestMessage.Body, CoreMessageType.JsonObject);
var responseMessage = await PeerProxy.GetResponseAsync(requestMessage).ConfigureAwait(false);
if (GeneratedProxyMemberReturnModel.TryDeserialize(responseMessage, out var returnModel))
{
diff --git a/src/dotnetCampus.Ipc/Context/KnownMessageHeaders.cs b/src/dotnetCampus.Ipc/Context/KnownMessageHeaders.cs
new file mode 100644
index 00000000..419d6c2b
--- /dev/null
+++ b/src/dotnetCampus.Ipc/Context/KnownMessageHeaders.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace dotnetCampus.Ipc.Context;
+
+///
+/// 已知的消息头
+///
+/// 现在已有三套通讯方法:
+/// - RemoteObject
+/// - MVC
+/// - Raw
+/// 其中 Raw 不加头,完全都裸通讯方式
+public enum KnownMessageHeaders : ulong
+{
+ ///
+ /// 发送的消息是 RemoteObject 通讯的消息
+ ///
+ RemoteObjectMessageHeader
+ // 消息头是 R(e)m(ote)O(b)j(ect) 的 RmOj 几个字符组成的 long 头
+ = 0x526D4F6A,
+}
diff --git a/src/dotnetCampus.Ipc/IpcMessageCommandType.cs b/src/dotnetCampus.Ipc/IpcMessageCommandType.cs
index 865e1d43..fdeedb04 100644
--- a/src/dotnetCampus.Ipc/IpcMessageCommandType.cs
+++ b/src/dotnetCampus.Ipc/IpcMessageCommandType.cs
@@ -41,35 +41,35 @@ internal enum IpcMessageCommandType : short
///
ResponseMessage = (1 << 2) | Business,
- ///
- /// 请求的细分类型,IPC 框架无法识别和处理此消息体。
- ///
- RawRequestMessage = (1 << 3) | RequestMessage,
+ /////
+ ///// 请求的细分类型,IPC 框架无法识别和处理此消息体。
+ /////
+ //RawRequestMessage = (1 << 3) | RequestMessage,
- ///
- /// 响应的细分类型,IPC 框架无法识别和处理此消息体。
- ///
- RawResponseMessage = (1 << 3) | ResponseMessage,
+ /////
+ ///// 响应的细分类型,IPC 框架无法识别和处理此消息体。
+ /////
+ //RawResponseMessage = (1 << 3) | ResponseMessage,
- ///
- /// 请求的细分类型,IPC 框架知道此消息体是可被处理的字符串。
- ///
- StringRequestMessage = (1 << 4) | RequestMessage,
+ /////
+ ///// 请求的细分类型,IPC 框架知道此消息体是可被处理的字符串。
+ /////
+ //StringRequestMessage = (1 << 4) | RequestMessage,
- ///
- /// 响应的细分类型,IPC 框架知道此消息体是可被处理的字符串。
- ///
- StringResponseMessage = (1 << 4) | ResponseMessage,
+ /////
+ ///// 响应的细分类型,IPC 框架知道此消息体是可被处理的字符串。
+ /////
+ //StringResponseMessage = (1 << 4) | ResponseMessage,
- ///
- /// 请求的细分类型,IPC 框架知道此消息体是可被处理的 .NET 对象。
- ///
- ObjectRequestMessage = (1 << 5) | RequestMessage,
+ /////
+ ///// 请求的细分类型,IPC 框架知道此消息体是可被处理的 .NET 对象。
+ /////
+ //ObjectRequestMessage = (1 << 5) | RequestMessage,
- ///
- /// 响应的细分类型,IPC 框架知道此消息体是可被处理的 .NET 对象。
- ///
- ObjectResponseMessage = (1 << 5) | ResponseMessage,
+ /////
+ ///// 响应的细分类型,IPC 框架知道此消息体是可被处理的 .NET 对象。
+ /////
+ //ObjectResponseMessage = (1 << 5) | ResponseMessage,
///
/// 其他消息。
diff --git a/src/dotnetCampus.Ipc/Messages/IpcMessage.cs b/src/dotnetCampus.Ipc/Messages/IpcMessage.cs
index d272b497..a83713c2 100644
--- a/src/dotnetCampus.Ipc/Messages/IpcMessage.cs
+++ b/src/dotnetCampus.Ipc/Messages/IpcMessage.cs
@@ -1,4 +1,6 @@
-using System.Diagnostics;
+using System;
+using System.Diagnostics;
+using dotnetCampus.Ipc.Context;
namespace dotnetCampus.Ipc.Messages
{
@@ -13,35 +15,22 @@ public readonly struct IpcMessage
/// 请标记此消息用于在调试过程中追踪。
/// IPC 消息的具体内容。
[DebuggerStepThrough]
- public IpcMessage(string tag, IpcMessageBody body)
+ public IpcMessage(string tag, IpcMessageBody body) : this(tag, body, (ulong) 0)
{
- Tag = tag;
- Body = body;
- CoreMessageType = CoreMessageType.Raw;
}
///
/// 创建一条可在 IPC 框架中传输的消息。
///
- /// 请标记此消息用于在调试过程中追踪。
- /// IPC 消息的具体内容。
+ ///
+ ///
+ ///
[DebuggerStepThrough]
- public IpcMessage(string tag, byte[] data) : this(tag, new IpcMessageBody(data))
- {
- }
-
- ///
- /// 创建一条可在 IPC 框架中传输的消息。
- ///
- /// 请标记此消息用于在调试过程中追踪。
- /// IPC 消息的具体内容。
- /// 由 IPC 框架传入,用以标记此消息可被 IPC 框架识别和处理的类型。
- [DebuggerStepThrough]
- internal IpcMessage(string tag, IpcMessageBody body, CoreMessageType coreMessageType)
+ public IpcMessage(string tag, IpcMessageBody body, ulong ipcMessageHeader)
{
Tag = tag;
Body = body;
- CoreMessageType = coreMessageType;
+ IpcMessageHeader = ipcMessageHeader;
}
///
@@ -49,9 +38,8 @@ internal IpcMessage(string tag, IpcMessageBody body, CoreMessageType coreMessage
///
/// 请标记此消息用于在调试过程中追踪。
/// IPC 消息的具体内容。
- /// 由 IPC 框架传入,用以标记此消息可被 IPC 框架识别和处理的类型。
[DebuggerStepThrough]
- internal IpcMessage(string tag, byte[] data, CoreMessageType coreMessageType) : this(tag, new IpcMessageBody(data), coreMessageType)
+ public IpcMessage(string tag, byte[] data) : this(tag, new IpcMessageBody(data))
{
}
@@ -65,9 +53,32 @@ internal IpcMessage(string tag, IpcMessageBody body, CoreMessageType coreMessage
///
public IpcMessageBody Body { get; }
+ /////
+ ///// 标记此消息可被 IPC 框架识别和处理的类型。
+ /////
+ //internal CoreMessageType CoreMessageType { get; }
+
///
- /// 标记此消息可被 IPC 框架识别和处理的类型。
+ /// 消息头类型,用来标识这条消息属于什么机制发送的消息。默认是 0 表示 Raw 裸消息。为 0 时,将不会带在发送的数据里面。框架内预设的消息类型,请参阅 类
///
- internal CoreMessageType CoreMessageType { get; }
+ public ulong IpcMessageHeader { get; }
+
+ ///
+ /// 调试使用的属性
+ ///
+ public KnownMessageHeaders Header => (KnownMessageHeaders) IpcMessageHeader;
+
+ internal IpcBufferMessageContext ToIpcBufferMessageContextWithMessageHeader(IpcMessageCommandType ipcMessageCommandType)
+ {
+ if (IpcMessageHeader == 0)
+ {
+ return new IpcBufferMessageContext(Tag, ipcMessageCommandType, Body);
+ }
+
+ var header = BitConverter.GetBytes(IpcMessageHeader);
+ var ipcBufferMessageContext =
+ new IpcBufferMessageContext(Tag, ipcMessageCommandType, new IpcMessageBody(header), Body);
+ return ipcBufferMessageContext;
+ }
}
}
diff --git a/src/dotnetCampus.Ipc/Messages/IpcMessageBody.cs b/src/dotnetCampus.Ipc/Messages/IpcMessageBody.cs
index 5d9a59d8..7cc2b1c8 100644
--- a/src/dotnetCampus.Ipc/Messages/IpcMessageBody.cs
+++ b/src/dotnetCampus.Ipc/Messages/IpcMessageBody.cs
@@ -59,6 +59,13 @@ public IpcMessageBody(byte[] buffer, int start, int length)
/// 数据长度
///
public int Length { get; }
+
+ internal static IpcMessageBody EmptyIpcMessageBody =>
+#if NET45
+ new IpcMessageBody(new byte[0]);
+#else
+ new IpcMessageBody(Array.Empty());
+#endif
}
///
diff --git a/src/dotnetCampus.Ipc/Pipes/IpcClientService.cs b/src/dotnetCampus.Ipc/Pipes/IpcClientService.cs
index 2876d56c..7e1daa8e 100644
--- a/src/dotnetCampus.Ipc/Pipes/IpcClientService.cs
+++ b/src/dotnetCampus.Ipc/Pipes/IpcClientService.cs
@@ -315,7 +315,7 @@ await IpcMessageConverter.WriteAsync
///
/// 业务层使用的
///
- internal async Task WriteMessageAsync(IpcMessageTracker tracker)
+ internal async Task WriteMessageAsync(IpcMessageTracker tracker)
{
VerifyNotDisposed();
@@ -341,10 +341,12 @@ async Task WriteMessageAsyncInner()
var stream = result.NamedPipeClientStream;
+ var ipcMessageBody = tracker.Message.Body;
+
// 追踪、校验消息。
var ack = AckManager.GetAck();
tracker.Debug("IPC start writing...");
- tracker.CriticalStep("SendCore", ack, tracker.Message);
+ tracker.CriticalStep("SendCore", ack, ipcMessageBody);
// 发送消息。
await IpcMessageConverter.WriteAsync
@@ -354,9 +356,9 @@ await IpcMessageConverter.WriteAsync
AckManager.GetAck(),
// 表示这是业务层的消息
IpcMessageCommandType.Business,
- tracker.Message.Buffer,
- tracker.Message.Start,
- tracker.Message.Length,
+ ipcMessageBody.Buffer,
+ ipcMessageBody.Start,
+ ipcMessageBody.Length,
IpcConfiguration.SharedArrayPool,
tracker.Tag
);
diff --git a/src/dotnetCampus.Ipc/Pipes/IpcMessageManagerBase.cs b/src/dotnetCampus.Ipc/Pipes/IpcMessageManagerBase.cs
index 19ab35d1..6f62e48e 100644
--- a/src/dotnetCampus.Ipc/Pipes/IpcMessageManagerBase.cs
+++ b/src/dotnetCampus.Ipc/Pipes/IpcMessageManagerBase.cs
@@ -14,45 +14,85 @@ class IpcMessageManagerBase
protected static IpcBufferMessageContext CreateResponseMessageInner(IpcClientRequestMessageId messageId, in IpcMessage response)
{
/*
- * MessageHeader
- * MessageId
- * Response Message Length
- * Response Message
- */
+ * MessageHeader
+ * MessageId
+ * Response Message Length
+ * Response Message
+ */
+ var messageLength = response.Body.Length;
var currentMessageIdByteList = BitConverter.GetBytes(messageId.MessageIdValue);
- var responseMessageLengthByteList = BitConverter.GetBytes(response.Body.Length);
+ IpcMessageBody businessHeader;
+ if (response.IpcMessageHeader == 0)
+ {
+ businessHeader = IpcMessageBody.EmptyIpcMessageBody;
+ }
+ else
+ {
+ // 需要带上头的消息
+ messageLength += sizeof(ulong);
+
+ // 有业务头,加上业务头
+ businessHeader = new IpcMessageBody(BitConverter.GetBytes(response.IpcMessageHeader));
+ }
+
+ var responseMessageLengthByteList = BitConverter.GetBytes(messageLength);
+
return new IpcBufferMessageContext
(
response.Tag,
- IpcMessageCommandType.ResponseMessage | response.CoreMessageType.AsMessageCommandTypeFlags(),
- new IpcMessageBody(ResponseMessageHeader),
- new IpcMessageBody(currentMessageIdByteList),
- new IpcMessageBody(responseMessageLengthByteList),
- response.Body
+ IpcMessageCommandType.ResponseMessage,
+ new[]
+ {
+ new IpcMessageBody(ResponseMessageHeader),
+ new IpcMessageBody(currentMessageIdByteList),
+ new IpcMessageBody(responseMessageLengthByteList),
+ businessHeader,
+ response.Body
+ }
);
}
protected static IpcBufferMessageContext CreateRequestMessageInner(in IpcMessage request, ulong currentMessageId)
{
/*
- * MessageHeader
- * MessageId
- * Request Message Length
- * Request Message
- */
+ * MessageHeader
+ * MessageId
+ * Request Message Length
+ * Request Message
+ */
var currentMessageIdByteList = BitConverter.GetBytes(currentMessageId);
- var requestMessageLengthByteList = BitConverter.GetBytes(request.Body.Length);
+ var messageLength = request.Body.Length;
+
+ IpcMessageBody businessHeader;
+ if (request.IpcMessageHeader == 0)
+ {
+ businessHeader = IpcMessageBody.EmptyIpcMessageBody;
+ }
+ else
+ {
+ // 需要带上头的消息
+ messageLength += sizeof(ulong);
+
+ // 有业务头,加上业务头
+ businessHeader = new IpcMessageBody(BitConverter.GetBytes(request.IpcMessageHeader));
+ }
+
+ var requestMessageLengthByteList = BitConverter.GetBytes(messageLength);
return new IpcBufferMessageContext
(
request.Tag,
- IpcMessageCommandType.RequestMessage | request.CoreMessageType.AsMessageCommandTypeFlags(),
- new IpcMessageBody(RequestMessageHeader),
- new IpcMessageBody(currentMessageIdByteList),
- new IpcMessageBody(requestMessageLengthByteList),
- request.Body
+ IpcMessageCommandType.RequestMessage,
+ new[]
+ {
+ new IpcMessageBody(RequestMessageHeader),
+ new IpcMessageBody(currentMessageIdByteList),
+ new IpcMessageBody(requestMessageLengthByteList),
+ businessHeader,
+ request.Body
+ }
);
}
diff --git a/src/dotnetCampus.Ipc/Pipes/PeerProxy.cs b/src/dotnetCampus.Ipc/Pipes/PeerProxy.cs
index ead5dec3..3952fffb 100644
--- a/src/dotnetCampus.Ipc/Pipes/PeerProxy.cs
+++ b/src/dotnetCampus.Ipc/Pipes/PeerProxy.cs
@@ -56,20 +56,43 @@ internal PeerProxy(string peerName, IpcClientService ipcClientService, IpcIntern
///
public async Task NotifyAsync(IpcMessage request)
{
- // 追踪业务消息。
- var requestTracker = new IpcMessageTracker(IpcContext.PipeName, PeerName, request.Body, request.Tag, IpcContext.Logger);
- requestTracker.CriticalStep("Send", null, request.Body);
+ if (request.IpcMessageHeader != 0)
+ {
+ // 追踪业务消息。
+ var requestTracker = new IpcMessageTracker(IpcContext.PipeName, PeerName, request, request.Tag, IpcContext.Logger);
+ requestTracker.CriticalStep("Send", null, request.Body);
- await WaitConnectAsync(requestTracker).ConfigureAwait(false);
+ await WaitConnectAsync(requestTracker).ConfigureAwait(false);
- try
- {
- // 发送带有追踪的请求。
- await IpcClientService.WriteMessageAsync(requestTracker).ConfigureAwait(false);
+ try
+ {
+ // 发送带有追踪的请求。
+ await IpcClientService.WriteMessageAsync(requestTracker).ConfigureAwait(false);
+ }
+ catch (Exception e)
+ {
+ throw new IpcRemoteException($"[{nameof(NotifyAsync)}] Tag:'{request.Tag}'; LocalPeer:'{IpcContext.PipeName}'; RemotePeer:'{PeerName}'; ExceptionMessage:'{e.Message}'", e);
+ }
}
- catch (Exception e)
+ else
{
- throw new IpcRemoteException($"[{nameof(NotifyAsync)}] Tag:'{request.Tag}'; LocalPeer:'{IpcContext.PipeName}'; RemotePeer:'{PeerName}'; ExceptionMessage:'{e.Message}'", e);
+ var ipcBufferMessageContext = request.ToIpcBufferMessageContextWithMessageHeader(IpcMessageCommandType.Business);
+
+ var requestTracker = new IpcMessageTracker(IpcContext.PipeName, PeerName, ipcBufferMessageContext, ipcBufferMessageContext.Tag, IpcContext.Logger);
+
+ requestTracker.CriticalStep("Send", null, request.Body);
+
+ await WaitConnectAsync(requestTracker).ConfigureAwait(false);
+
+ try
+ {
+ // 发送带有追踪的请求。
+ await IpcClientService.WriteMessageAsync(requestTracker).ConfigureAwait(false);
+ }
+ catch (Exception e)
+ {
+ throw new IpcRemoteException($"[{nameof(NotifyAsync)}] Tag:'{request.Tag}'; LocalPeer:'{IpcContext.PipeName}'; RemotePeer:'{PeerName}'; ExceptionMessage:'{e.Message}'", e);
+ }
}
}
diff --git a/src/dotnetCampus.Ipc/Utils/Extensions/IpcMessageExtension.cs b/src/dotnetCampus.Ipc/Utils/Extensions/IpcMessageExtension.cs
new file mode 100644
index 00000000..248ef51b
--- /dev/null
+++ b/src/dotnetCampus.Ipc/Utils/Extensions/IpcMessageExtension.cs
@@ -0,0 +1,29 @@
+using System;
+using dotnetCampus.Ipc.Messages;
+
+namespace dotnetCampus.Ipc.Utils.Extensions;
+
+static class IpcMessageExtension
+{
+ public static IpcMessage Skip(this IpcMessage ipcMessage, int length)
+ {
+ return new IpcMessage(ipcMessage.Tag, new IpcMessageBody(ipcMessage.Body.Buffer,
+ ipcMessage.Body.Start + length,
+ ipcMessage.Body.Length - length));
+ }
+
+ public static bool TryReadBusinessHeader(this in IpcMessage ipcMessage, out ulong header)
+ {
+ var length = sizeof(ulong);
+ if (ipcMessage.Body.Length < length)
+ {
+ header = 0;
+ return false;
+ }
+ else
+ {
+ header = BitConverter.ToUInt64(ipcMessage.Body.Buffer, ipcMessage.Body.Start);
+ return true;
+ }
+ }
+}