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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Raphael.Tcp.Tools" Version="2.0.1">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Raphael.Tcp.Tools" Version="2.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Raphael.Tcp.Tools">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Raphael.Tcp.Tools --version 2.0.1
                    
#r "nuget: Raphael.Tcp.Tools, 2.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Raphael.Tcp.Tools@2.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Raphael.Tcp.Tools&version=2.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Raphael.Tcp.Tools&version=2.0.1
                    
Install as a Cake Tool

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, GunServiceGunHandlerBase);
  • the method is synchronous (returns the response, not Task<T>);
  • it receives your Connection instead of gRPC's ServerCallContext;
  • a google.protobuf.Empty response maps to a void handler with no ReplyMsgId (the explicit "no canonical auto-reply" signal — the handler pushes any packets itself via the Connection).

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;
  • MsgId members are the exact message type names — PingRequest, PongReply, etc. (no prefix, no CS_/SC_ rewriting);
  • the MsgId enum 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).
  • MsgId enum members matching the generated names:
    • default: the exact message type name;
    • with TcpMsgIdPrefix: <prefix><MessageName>;
    • with TcpNormalizeCsScPrefix: a leading CS_/SC_ becomes Cs/Sc.
  • Streaming rpcs are skipped (unary only).

License

Apache-2.0 (this is a fork of grpc/grpc).

There are no supported framework assets in this package.

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.

Version Downloads Last Updated
2.0.1 65 6/2/2026
2.0.0 71 6/2/2026
1.2.1 67 6/2/2026
1.2.0 84 5/31/2026
1.1.2 76 5/30/2026
1.1.1 88 5/30/2026
1.1.0 77 5/30/2026
1.0.0 84 5/30/2026

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.