Skip to content

Commit

Permalink
Merge pull request #122 from dotnet-campus/t/lindexi/IpcProxy
Browse files Browse the repository at this point in the history
消息加上业务头,可以在核心框架之外的业务对接框架上,使用不同的对接方式
  • Loading branch information
walterlv authored Mar 14, 2023
2 parents 04317aa + 9283e36 commit 6a75b1b
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 91 deletions.
Original file line number Diff line number Diff line change
@@ -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
{
Expand Down Expand Up @@ -69,7 +72,11 @@ public string Id
/// <returns></returns>
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);
}

/// <summary>
Expand All @@ -80,7 +87,19 @@ public static IpcMessage Serialize(GeneratedProxyMemberInvokeModel model)
/// <returns></returns>
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;
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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))
{
Expand Down
23 changes: 23 additions & 0 deletions src/dotnetCampus.Ipc/Context/KnownMessageHeaders.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace dotnetCampus.Ipc.Context;

/// <summary>
/// 已知的消息头
/// </summary>
/// 现在已有三套通讯方法:
/// - RemoteObject
/// - MVC
/// - Raw
/// 其中 Raw 不加头,完全都裸通讯方式
public enum KnownMessageHeaders : ulong
{
/// <summary>
/// 发送的消息是 RemoteObject 通讯的消息
/// </summary>
RemoteObjectMessageHeader
// 消息头是 R(e)m(ote)O(b)j(ect) 的 RmOj 几个字符组成的 long 头
= 0x526D4F6A,
}
48 changes: 24 additions & 24 deletions src/dotnetCampus.Ipc/IpcMessageCommandType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,35 +41,35 @@ internal enum IpcMessageCommandType : short
/// </summary>
ResponseMessage = (1 << 2) | Business,

/// <summary>
/// 请求的细分类型,IPC 框架无法识别和处理此消息体。
/// </summary>
RawRequestMessage = (1 << 3) | RequestMessage,
///// <summary>
///// 请求的细分类型,IPC 框架无法识别和处理此消息体。
///// </summary>
//RawRequestMessage = (1 << 3) | RequestMessage,

/// <summary>
/// 响应的细分类型,IPC 框架无法识别和处理此消息体。
/// </summary>
RawResponseMessage = (1 << 3) | ResponseMessage,
///// <summary>
///// 响应的细分类型,IPC 框架无法识别和处理此消息体。
///// </summary>
//RawResponseMessage = (1 << 3) | ResponseMessage,

/// <summary>
/// 请求的细分类型,IPC 框架知道此消息体是可被处理的字符串。
/// </summary>
StringRequestMessage = (1 << 4) | RequestMessage,
///// <summary>
///// 请求的细分类型,IPC 框架知道此消息体是可被处理的字符串。
///// </summary>
//StringRequestMessage = (1 << 4) | RequestMessage,

/// <summary>
/// 响应的细分类型,IPC 框架知道此消息体是可被处理的字符串。
/// </summary>
StringResponseMessage = (1 << 4) | ResponseMessage,
///// <summary>
///// 响应的细分类型,IPC 框架知道此消息体是可被处理的字符串。
///// </summary>
//StringResponseMessage = (1 << 4) | ResponseMessage,

/// <summary>
/// 请求的细分类型,IPC 框架知道此消息体是可被处理的 .NET 对象。
/// </summary>
ObjectRequestMessage = (1 << 5) | RequestMessage,
///// <summary>
///// 请求的细分类型,IPC 框架知道此消息体是可被处理的 .NET 对象。
///// </summary>
//ObjectRequestMessage = (1 << 5) | RequestMessage,

/// <summary>
/// 响应的细分类型,IPC 框架知道此消息体是可被处理的 .NET 对象。
/// </summary>
ObjectResponseMessage = (1 << 5) | ResponseMessage,
///// <summary>
///// 响应的细分类型,IPC 框架知道此消息体是可被处理的 .NET 对象。
///// </summary>
//ObjectResponseMessage = (1 << 5) | ResponseMessage,

/// <summary>
/// 其他消息。
Expand Down
59 changes: 35 additions & 24 deletions src/dotnetCampus.Ipc/Messages/IpcMessage.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Diagnostics;
using System;
using System.Diagnostics;
using dotnetCampus.Ipc.Context;

namespace dotnetCampus.Ipc.Messages
{
Expand All @@ -13,45 +15,31 @@ public readonly struct IpcMessage
/// <param name="tag">请标记此消息用于在调试过程中追踪。</param>
/// <param name="body">IPC 消息的具体内容。</param>
[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;
}

/// <summary>
/// 创建一条可在 IPC 框架中传输的消息。
/// </summary>
/// <param name="tag">请标记此消息用于在调试过程中追踪。</param>
/// <param name="data">IPC 消息的具体内容。</param>
/// <param name="tag"></param>
/// <param name="body"></param>
/// <param name="ipcMessageHeader"></param>
[DebuggerStepThrough]
public IpcMessage(string tag, byte[] data) : this(tag, new IpcMessageBody(data))
{
}

/// <summary>
/// 创建一条可在 IPC 框架中传输的消息。
/// </summary>
/// <param name="tag">请标记此消息用于在调试过程中追踪。</param>
/// <param name="body">IPC 消息的具体内容。</param>
/// <param name="coreMessageType">由 IPC 框架传入,用以标记此消息可被 IPC 框架识别和处理的类型。</param>
[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;
}

/// <summary>
/// 创建一条可在 IPC 框架中传输的消息。
/// </summary>
/// <param name="tag">请标记此消息用于在调试过程中追踪。</param>
/// <param name="data">IPC 消息的具体内容。</param>
/// <param name="coreMessageType">由 IPC 框架传入,用以标记此消息可被 IPC 框架识别和处理的类型。</param>
[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))
{
}

Expand All @@ -65,9 +53,32 @@ internal IpcMessage(string tag, IpcMessageBody body, CoreMessageType coreMessage
/// </summary>
public IpcMessageBody Body { get; }

///// <summary>
///// 标记此消息可被 IPC 框架识别和处理的类型。
///// </summary>
//internal CoreMessageType CoreMessageType { get; }

/// <summary>
/// 标记此消息可被 IPC 框架识别和处理的类型。
/// 消息头类型,用来标识这条消息属于什么机制发送的消息。默认是 0 表示 Raw 裸消息。为 0 时,将不会带在发送的数据里面。框架内预设的消息类型,请参阅 <see cref="KnownMessageHeaders"/> 类
/// </summary>
internal CoreMessageType CoreMessageType { get; }
public ulong IpcMessageHeader { get; }

/// <summary>
/// 调试使用的属性
/// </summary>
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;
}
}
}
7 changes: 7 additions & 0 deletions src/dotnetCampus.Ipc/Messages/IpcMessageBody.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ public IpcMessageBody(byte[] buffer, int start, int length)
/// 数据长度
/// </summary>
public int Length { get; }

internal static IpcMessageBody EmptyIpcMessageBody =>
#if NET45
new IpcMessageBody(new byte[0]);
#else
new IpcMessageBody(Array.Empty<byte>());
#endif
}

/// <summary>
Expand Down
12 changes: 7 additions & 5 deletions src/dotnetCampus.Ipc/Pipes/IpcClientService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ await IpcMessageConverter.WriteAsync
/// <remarks>
/// 业务层使用的
/// </remarks>
internal async Task WriteMessageAsync(IpcMessageTracker<IpcMessageBody> tracker)
internal async Task WriteMessageAsync(IpcMessageTracker<IpcMessage> tracker)
{
VerifyNotDisposed();

Expand All @@ -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
Expand All @@ -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
);
Expand Down
Loading

0 comments on commit 6a75b1b

Please sign in to comment.