Raphael.Tcp.Tools
2.0.1
dotnet add package Raphael.Tcp.Tools --version 2.0.1
NuGet\Install-Package Raphael.Tcp.Tools -Version 2.0.1
<PackageReference Include="Raphael.Tcp.Tools" Version="2.0.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Raphael.Tcp.Tools" Version="2.0.1" />
<PackageReference Include="Raphael.Tcp.Tools"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Raphael.Tcp.Tools --version 2.0.1
#r "nuget: Raphael.Tcp.Tools, 2.0.1"
#:package Raphael.Tcp.Tools@2.0.1
#addin nuget:?package=Raphael.Tcp.Tools&version=2.0.1
#tool nuget:?package=Raphael.Tcp.Tools&version=2.0.1
Raphael.Tcp.Tools
Self-contained protoc build-time tooling that generates synchronous TCP
packet-handler service bases — plus the C# message classes — from your
.proto files, instead of gRPC's HTTP/2 async stubs.
It ships its own protoc, a forked grpc_csharp_plugin (gRPC's C# code
generator, modified) and the well-known-type proto includes, so a service in a
.proto becomes a top-level abstract handler base you implement on a raw TCP
packet server — no HTTP/2, no ServerCallContext, no async Task<T>, and no
Grpc.Tools dependency.
For each unary rpc Ping (PingRequest) returns (PongReply) it emits:
public abstract partial class GunHandlerBase : global::MyApp.Net.IPacketHandler
{
[PacketHandler(MsgId.PingRequest, MsgId.PongReply)]
public virtual PongReply Ping(PingRequest request, Connection connection)
=> throw new NotImplementedException("Ping is not implemented.");
}
- no static wrapper service class is generated;
- handler class name is
<ServiceNameWithoutService>HandlerBase(for example,GunService→GunHandlerBase); - the method is synchronous (returns the response, not
Task<T>); - it receives your
Connectioninstead of gRPC'sServerCallContext; - a
google.protobuf.Emptyresponse maps to avoidhandler with noReplyMsgId(the explicit "no canonical auto-reply" signal — the handler pushes any packets itself via theConnection).
Zero-config default
With no MSBuild properties set, the generator assumes everything lives in the
proto's own csharp_namespace:
- handler/attribute/connection types default to
<csharp_namespace>.IPacketHandler,<csharp_namespace>.PacketHandlerAttribute,<csharp_namespace>.Connection; MsgIdmembers are the exact message type names —PingRequest,PongReply, etc. (no prefix, noCS_/SC_rewriting);- the
MsgIdenum itself is<csharp_namespace>.MsgId; - generated files land in the
obj/root.
<ItemGroup>
<PackageReference Include="Raphael.Tcp.Tools" Version="2.0.0" />
<PackageReference Include="Google.Protobuf" Version="3.27.0" />
<Protobuf Include="protos\**\*.proto" />
</ItemGroup>
Your project must define the four referenced types (IPacketHandler,
PacketHandlerAttribute, Connection, and a MsgId enum whose members match
the generated names) in the proto's csharp_namespace.
Customization
Everything above is overridable from the consuming project's PropertyGroup.
Every property is optional — set only what you need. The block below shows the
complete set of configurable properties:
<PropertyGroup>
<TcpIPacketHandler>Custom.Server.IPacketHandler</TcpIPacketHandler>
<TcpPacketHandlerAttr>Custom.Server.PacketHandlerAttribute</TcpPacketHandlerAttr>
<TcpConnection>Custom.Server.Connection</TcpConnection>
<TcpMsgId>Custom.Server.PacketTypes</TcpMsgId>
<TcpMsgIdPrefix>Msg</TcpMsgIdPrefix>
<TcpNormalizeCsScPrefix>true</TcpNormalizeCsScPrefix>
<TcpOutDir>Generated</TcpOutDir>
<TcpProtoDir>$(MSBuildProjectDirectory)\protos</TcpProtoDir>
<TcpProtocExe>$(MyTools)\protoc.exe</TcpProtocExe>
<TcpPluginExe>$(MyTools)\grpc_csharp_plugin.exe</TcpPluginExe>
</PropertyGroup>
| Property | Default | Effect |
|---|---|---|
TcpIPacketHandler |
<csharp_namespace>.IPacketHandler |
FQN of the interface the generated base implements |
TcpPacketHandlerAttr |
<csharp_namespace>.PacketHandlerAttribute |
FQN of the [PacketHandler] attribute |
TcpConnection |
<csharp_namespace>.Connection |
FQN of the per-call connection type |
TcpMsgId |
<csharp_namespace>.MsgId |
FQN of the MsgId enum type used in the attributes |
TcpMsgIdPrefix |
(empty) | String prepended to the exact message name for each MsgId member (PingRequest → <prefix>PingRequest) |
TcpNormalizeCsScPrefix |
false |
When true, rewrite a leading CS_/SC_ to Cs/Sc before applying TcpMsgIdPrefix |
TcpOutDir |
$(IntermediateOutputPath) (obj/ root) |
Output dir for both the message file and the *Tcp.cs |
TcpProtoDir |
(unset) | Escape hatch: glob this directory for protos instead of using <Protobuf> items |
TcpProtocExe |
bundled windows_x64\protoc.exe |
Override the protoc binary used for codegen |
TcpPluginExe |
bundled windows_x64\grpc_csharp_plugin.exe |
Override the TCP plugin binary used for codegen |
Inputs are read from your <Protobuf Include="..." /> items by default. Generated
files are compiled automatically, regenerated on build, and need not be committed.
Platform support
Windows-x64 only in this version. On other platforms the build fails with a
clear error. To use it elsewhere, build protoc and the forked plugin for your
platform and set TcpProtocExe / TcpPluginExe.
Requirements
- A
[PacketHandler]attribute whose constructor accepts(MsgId request)and(MsgId request, MsgId reply). MsgIdenum members matching the generated names:- default: the exact message type name;
- with
TcpMsgIdPrefix:<prefix><MessageName>; - with
TcpNormalizeCsScPrefix: a leadingCS_/SC_becomesCs/Sc.
- Streaming rpcs are skipped (unary only).
License
Apache-2.0 (this is a fork of grpc/grpc).
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
2.0.1: the MsgId enum type is now configurable via TcpMsgId (plugin option msgid); defaults to <csharp_namespace>.MsgId as before. 2.0.0 (breaking): self-contained - no longer depends on Grpc.Tools; ships its own protoc, plugin and well-known-type includes, and now generates the C# message classes itself (--csharp_out) alongside the TCP bases. Zero-config default: handler/attr/connection types default to the proto's csharp_namespace (<ns>.IPacketHandler / .PacketHandlerAttribute / .Connection), MsgId members default to the exact message names (no prefix, no CS_/SC_ normalization). Input is read from the consumer's <Protobuf Include=...> items; output goes to the obj/ root by default. TcpMsgIdPrefix now prepends only; CS_/SC_ normalization is opt-in via TcpNormalizeCsScPrefix. See CHANGELOG.md.