Skip to content

Instantly share code, notes, and snippets.

@bgilbert6
Last active April 22, 2020 22:23
Show Gist options
  • Save bgilbert6/ac6bec84c39b0fe1912bf2c88b96969f to your computer and use it in GitHub Desktop.
Save bgilbert6/ac6bec84c39b0fe1912bf2c88b96969f to your computer and use it in GitHub Desktop.
SignalR RPC wrapper for server calls
hubConnection.invoke('Call', 'JoinLobby', {LobbyToken: this.lobbyToken});
public class ExampleHub : Hub
{
private readonly IServiceProvider provider;
public Dictionary<string, Type> RpcMethods = new Dictionary<string, Type>();
private Dictionary<Type, IWebSocketRpc> RpcInstances = new Dictionary<Type, IWebSocketRpc>();
public ExampleHub(IServiceProvider provider)
{
this.provider = provider;
if(!RpcMethods.Any())
{
//could probably search for all types that implement IWebSocketRpc interfance
RpcMethods.Add("JoinLobby", typeof(JoinLobbyRpc));
}
}
public async Task Call(string rpc, JsonElement data)
{
if (!RpcMethods.ContainsKey(rpc))
{
throw new Exception("Unknown rpc type: " + rpc);
}
var type = RpcMethods[rpc];
if (!RpcInstances.ContainsKey(type))
{
//allows DI
RpcInstances[type] = (IWebSocketRpc)ActivatorUtilities.CreateInstance(provider, type);
}
await RpcInstances[type].Call(data, Context, Clients);
}
}
public interface IWebSocketRpc
{
public string RpcName { get; }
public Task Call(JsonElement data, HubCallerContext context, IHubCallerClients clients);
}
//this is just an example usage
public class JoinLobbyData
{
public string LobbyToken { get; set; }
}
public class JoinLobbyRpc : RpcBase<JoinLobbyData>
{
private readonly DbContext db;
public override string RpcName => "JoinLobby";
public JoinLobbyRpc(DbContext db)
{
this.db = db;
}
public override Task Call(JoinLobbyData data, HubCallerContext context, IHubCallerClients clients)
{
//example DB call
var lobby = db.Lobbys.Where(x => x.Token == data.LobbyToken).FirstOrDefault();
//return clients.Client(context.ConnectionId).SendAsync("SendChat", "Joined Lobby.");
return Task.CompletedTask;
}
}
public abstract class RpcBase<T> : IWebSocketRpc
{
public abstract string RpcName { get; }
public virtual Task Call(JsonElement data, HubCallerContext context, IHubCallerClients clients)
{
var json = data.GetRawText();
return Call(JsonSerializer.Deserialize<T>(json), context, clients);
}
public abstract Task Call(T data, HubCallerContext context, IHubCallerClients clients);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment