Skip to content

v0.36.0 [MetaServiceContract] server-side contract APIs, framework subscribers removed

Choose a tag to compare

@dmitry-lebedev dmitry-lebedev released this 29 Jul 17:00
· 18 commits to main since this release

[MetaServiceContract] — server code addresses a service by contract

Framework subscriber interfaces are gone as a mechanism. ILobbySubscriber becomes
ILobbyListener: an ordinary contract a meta service inherits, whose methods are ordinary meta
methods with real ids, dispatcher cases and client-side replay.

Mark a contract [MetaServiceContract] and the generator emits an awaitable mirror into the
contract's own assembly
— which is what lets code that cannot reference the game make a typed call:

[MetaServiceContract]
public interface ILobbyListener { void OnMatchFound(MatchFoundEvent e); }
// generated beside it: Task OnMatchFoundAsync(string entityId, MatchFoundEvent e)

[MetaService(StateType = typeof(ProfileState))]
public interface IProfileService : IMetaService, ILobbyListener { }

public partial class ProfileService : IProfileService
{
    [MetaMethod(Alias = "OnMatchFound", Mode = ExecutionMode.Server, GenerateClientApi = false)]
    public void OnMatchFound(MatchFoundEvent e) => State.CurrentGameId = e.MatchId;
}

// framework side — inject once, entity id per call
public LobbyGrain(ILogger<LobbyGrain> logger, ILobbyListenerServerApi? players = null) { ... }
await _players.OnMatchFoundAsync(entityId, evt);
The entity id is an argument, not a binding, so one injected instance serves every target. Delivery
is a normal dispatch — state, broadcast, persistence, client replay — is awaited, so a
target-side failure reaches the caller, and works on a cold entity, so an offline player finds the
result waiting on next subscribe.