feat: add ERP agent pet bridge and startup guide

This commit is contained in:
郎速科技
2026-08-14 14:28:28 +08:00
parent a803070819
commit 4c08f4c948
252 changed files with 134752 additions and 72 deletions
@@ -0,0 +1,53 @@
using System.Buffers.Binary;
namespace Lskj.AgentPet.Host.Core.ErpBridge;
public static class BridgeFrameCodec
{
public const int MaxMessageBytes = 1024 * 1024;
public static async Task WriteAsync(
Stream stream,
ReadOnlyMemory<byte> body,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(stream);
if (body.Length is <= 0 or > MaxMessageBytes)
throw new HostError("bridge_protocol_error", "ERP 桥请求长度无效或超过 1 MB。");
byte[] header = new byte[4];
BinaryPrimitives.WriteInt32LittleEndian(header, body.Length);
await stream.WriteAsync(header, cancellationToken).ConfigureAwait(false);
await stream.WriteAsync(body, cancellationToken).ConfigureAwait(false);
await stream.FlushAsync(cancellationToken).ConfigureAwait(false);
}
public static async Task<byte[]> ReadAsync(
Stream stream,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(stream);
byte[] header = new byte[4];
await ReadExactlyAsync(stream, header, cancellationToken).ConfigureAwait(false);
int length = BinaryPrimitives.ReadInt32LittleEndian(header);
if (length is <= 0 or > MaxMessageBytes)
throw new HostError("bridge_protocol_error", "ERP 桥响应长度无效或超过 1 MB。");
byte[] body = new byte[length];
await ReadExactlyAsync(stream, body, cancellationToken).ConfigureAwait(false);
return body;
}
private static async Task ReadExactlyAsync(
Stream stream,
Memory<byte> target,
CancellationToken cancellationToken)
{
int offset = 0;
while (offset < target.Length)
{
int count = await stream.ReadAsync(target[offset..], cancellationToken).ConfigureAwait(false);
if (count == 0)
throw new HostError("bridge_disconnected", "ERP 桥在完整消息到达前关闭。");
offset += count;
}
}
}