Add 2023 R2 gRPC transport (RemoteGrpc) reusing native byte payloads
Stands up HistorianTransport.RemoteGrpc end-to-end for the read path, built on the recovered 2023 R2 gRPC contract (gRPC-Web/HTTP-1.1, port 32565, gzip). The opaque protobuf `bytes` fields carry the SAME native binary payloads as the 2020 WCF/MDAS path, so the proven serializers and parsers are reused unchanged. - Grpc/Protos/*.proto: 6 protoc-validated contracts recovered from embedded FileDescriptors (authoritative, not guessed). - Grpc/HistorianGrpcChannelFactory: GrpcWebHandler/HTTP-1.1 channel, ResolvePort/ResolveAddress, optional TLS + gzip. - Grpc/HistorianGrpcReadOrchestrator: mirrors the WCF read chain over gRPC; auth uses HistoryService.ExchangeKey (the gRPC ValCl op). - Wcf/HistorianNativeHandshake: transport-agnostic Open2 request builder + SSPI/Negotiate token loop + response decode, shared by WCF and gRPC. - Op map (2020 -> gRPC): ValCl->ExchangeKey, Open2->OpenConnection, StartQuery2->StartQuery, GetNextQueryResultBuffer2->GetNextQueryResultBuffer. - HistorianClientOptions: DefaultGrpcPort=32565, GrpcUseTls. - csproj: Google.Protobuf, Grpc.Net.Client(.Web), Grpc.Tools codegen. Not yet live-verified against a 2023 R2 server: ExchangeKey is the first thing to revisit if a live server rejects the handshake; the inner byte payloads are the proven 2020 protocol. Gated live test via HISTORIAN_GRPC_HOST. 188 unit tests green; build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,9 @@ public sealed class HistorianClientOptions
|
||||
{
|
||||
public const int DefaultPort = 32568;
|
||||
|
||||
/// <summary>Default TCP port of the 2023 R2 Historian Client Access Point gRPC endpoint.</summary>
|
||||
public const int DefaultGrpcPort = 32565;
|
||||
|
||||
public required string Host { get; init; }
|
||||
|
||||
public int Port { get; init; } = DefaultPort;
|
||||
@@ -49,4 +52,14 @@ public sealed class HistorianClientOptions
|
||||
/// that don't validate a server certificate.
|
||||
/// </summary>
|
||||
public string? ServerDnsIdentity { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// For <see cref="HistorianTransport.RemoteGrpc"/>: when true the channel uses TLS
|
||||
/// (<c>https://</c>); when false it uses plaintext (<c>http://</c>). Matches the stock
|
||||
/// 2023 R2 client's <c>securedConnection</c> flag. The TLS host is taken from
|
||||
/// <see cref="ServerDnsIdentity"/> when set (to match the server certificate's name),
|
||||
/// otherwise <see cref="Host"/>. When <see cref="AllowUntrustedServerCertificate"/> is
|
||||
/// true the server certificate chain is not validated. Default false.
|
||||
/// </summary>
|
||||
public bool GrpcUseTls { get; init; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user