Silky Microservice FrameworkSilky Microservice Framework
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
  • Introduction

    • Silky Framework Overview
  • Getting Started

    • Glossary
    • Quick Start
    • Project Template
    • Microservice Architecture
    • Sample Projects
  • Host & Module

    • Host Types
    • Gateway Configuration
    • Module System
    • Plugin System
  • Gateway & HTTP

    • Swagger / OpenAPI
    • MiniProfiler
    • CORS
    • Audit Logging
  • Service & RPC

    • App Services & Service Entries
    • RPC Communication
    • WebSocket
    • Service Registry
    • Service Governance
  • Data & Cache

    • EFCore Data Access
    • Caching
    • Distributed Lock
  • Security & Auth

    • Identity & Authentication
    • Distributed Transactions
  • Infrastructure

    • Dependency Injection
    • Object Mapping
    • Validation
    • Link Tracking (SkyAPM)
    • Logging (Serilog)
    • Health Checks
    • Message Bus (MassTransit)
    • Unit & Integration Testing

What is RPC?

RPC (Remote Procedure Call) is an inter-process communication mechanism that allows you to call a remote service as if it were a local function. An RPC framework hides the underlying transport (TCP/UDP), serialization format (XML/JSON/binary), and network details, so callers only need to know what remote interface exists and where — not how it works under the hood.

Key characteristics:

  • Hides network communication details (no direct Socket or HTTP handling)
  • Request/response model: client sends a request, server returns a response
  • The calling experience mirrors a local function call

An RPC framework consists of three roles:

  1. Service Provider: runs on the server side; defines and implements the service interface
  2. Service Publisher: runs on the RPC server; publishes the local service as a remote service for consumers
  3. Local Service Proxy: runs on the RPC client; proxies calls to the remote provider and wraps the result

How Silky RPC Works

Silky uses DotNetty as the transport layer and implements RPC over persistent TCP connections. The key technical challenges it addresses:

  1. Remote service definition: Services are defined as C# interfaces annotated with [ServiceRoute]. Consumers reference the interface project (or NuGet package) to gain access to service metadata.
  2. Dynamic proxy: Implemented via Autofac.Extras.DynamicProxy — injecting an interface automatically generates a local dynamic proxy that wraps remote calls transparently.
  3. Transport: Silky uses DotNetty as the underlying communication framework; the RPC protocol is transport-agnostic.
  4. Serialization: Objects are serialized to binary for network transfer. Silky uses JSON by default and also supports MessagePack and ProtoBuf.

Calling a Remote Service

Via Interface Proxy (Recommended)

In practice, the service definition (interface) and implementation (class) live in separate assemblies so the interface can be referenced by other services.

Step 1: Define the application service interface in a separate project:

namespace Demo.Contracts;

[ServiceRoute]
public interface IOrderAppService
{
    Task<OrderOutput> CreateAsync(CreateOrderInput input);
    Task<OrderOutput> GetAsync(long id);
}

Step 2: The consumer references the interface project (or its NuGet package).

Step 3: Inject and use the interface — Silky generates the dynamic proxy automatically:

public class ShoppingCartAppService : IShoppingCartAppService, IScopedDependency
{
    private readonly IOrderAppService _orderService;  // remote interface

    public ShoppingCartAppService(IOrderAppService orderService)
    {
        _orderService = orderService;
    }

    public async Task<string> CheckoutAsync(CheckoutInput input)
    {
        var order = await _orderService.CreateAsync(new CreateOrderInput
        {
            ProductId = input.ProductId,
            Quantity = input.Quantity,
        });
        return order.Id.ToString();
    }
}

Service Entry ID

Every method on a service interface generates a unique Service Entry ID used to route RPC calls:

ServiceEntryId = FullyQualifiedMethodName + ParameterNames + _ + HttpVerb

Example — the GetAsync(long id) method on IOrderAppService generates:

Demo.Contracts.IOrderAppService.GetAsync.id_Get

Governance Options

Every service entry inherits from the global Governance configuration and can be overridden via [Governance] attribute:

[ServiceRoute]
public interface IOrderAppService
{
    [Governance(TimeoutMillSeconds = 3000, RetryTimes = 2)]
    Task<OrderOutput> CreateAsync(CreateOrderInput input);

    [HttpGet("{id}")]
    [Governance(ShuntStrategy = ShuntStrategy.HashAlgorithm)]
    Task<OrderOutput> GetAsync([HashKey] long id);
}

RPC Security

All internal RPC communication is protected by a shared rpc.token:

rpc:
  token: "a-shared-secret-known-only-to-cluster-services"
  isSsl: false  # set true to enable SSL/TLS

External callers cannot access RPC ports directly — they must go through the API gateway.

Serialization

FormatPackageNotes
JSONBuilt-in (default)Human-readable, best compatibility
MessagePackSilky.Rpc.MessagePackCompact binary, high performance
ProtoBufSilky.Rpc.ProtoBufSchema-based, cross-language

Configure via:

rpc:
  codec: Json  # Json | MessagePack | ProtoBuf
Edit this page
Prev
App Services & Service Entries
Next
WebSocket