SignalR.EasyUse is a framework that helps eliminate contract mismatch errors when developing client and server applications in C# using SignalR.
- Create a new class library project in your solution that will contain contracts.
- Add the NuGet package to this project:
Install-Package SignalR.EasyUse.Interface
- Create an interface with server methods. The interface method names will be used as identifiers, and the parameters will be passed directly. The method's return type must be Task or Task<TResult>.
- Optionally, the interface can inherit from
SignalR.EasyUse.Interface.IServerMethods
to easily distinguish server methods, though this is not required.
Example:
public interface IChatHub: IServerMethods
{
Task SendMessage(string user, string message);
Task<List<User>> Login(string name, byte[] photo);
}
- Define client methods (those called by the server) by creating a class for each method. The class name will be used as an identifier, and all public properties of the class will be passed as parameters in the order they are declared.
- Optionally, these classes can inherit from
SignalR.EasyUse.Interface.IClientMethod
, but it’s not mandatory.
Example:
public class ReceiveMessage: IClientMethod
{
public string User { get; set; }
public string Message { get; set; }
}
- Add a reference to the project containing the contracts.
- Add the NuGet package to the server project:
Install-Package SignalR.EasyUse.Server
- Implement your server interface. Since the interface defines the contract, your hub will comply with it.
- Use strongly typed client calls with the extension method to send messages:
async Task SendAsync<T>(this IClientProxy clients, T payload)
Example:
public class ChatHub : Hub, IChatHub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync(new ReceiveMessage
{
User = user,
Message = message,
});
// Equivalent native call
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
- Add a reference to the project containing the contracts.
- Add the NuGet package to the client project:
Install-Package SignalR.EasyUse.Client
- Create a connection to the hub as usual:
_connection = new HubConnectionBuilder()
.WithUrl("http://localhost:53353/ChatHub")
.Build();
- Create a dynamic proxy for the hub based on the interface:
var hub = _connection.CreateHub<IChatHub>();
- Use the proxy to call server methods:
var users = await hub.Login(UserName, Photo);
await hub.SendMessage(UserName, MessageText);
Without EasyUse, the same call would look like this:
var users = await connection.InvokeCoreAsync<List<User>>("Login", new object[] { UserName, Photo });
await _connection.InvokeAsync("SendMessage", UserName, MessageText);
- To subscribe to messages from the server, use the extension method:
void Subscribe<T>(this HubConnection connection, Action<T> action)
Example:
_connection.Subscribe<ReceiveMessage>(data =>
{
var newMessage = $"{data.User}: {data.Message}";
Messages.Add(newMessage);
});
Without EasyUse, the same subscription would look like this:
_connection.On<string, string>("ReceiveMessage", (user, message) =>
{
var newMessage = $"{user}: {message}";
Messages.Add(newMessage);
});
If you'd like to explore a working project using this framework, check out these sample applications:
- Simple chat server on .NetCore 3.1 with three clients: WPF(.Net 4.6.1), WPF(.NetCore 3.1), and AvaloniaUI MVVM(.NetCore 3.1)
- A more feature-rich chat with beautiful design using MVVM (server on .NetCore 3.1, client on WPF MVVM(.Net 4.6.2))
Suggestions and feedback are welcome. Feel free to reach out via Telegram.