Skip to content

Commit

Permalink
updated readme to the latest changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Bieber committed Dec 17, 2014
1 parent de1b985 commit 1dd6300
Showing 1 changed file with 85 additions and 116 deletions.
201 changes: 85 additions & 116 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,142 +6,111 @@ One thing that really bugged me out about SignalR is the lack of strongly typed
This library will enable this feature via interface implementations.

## Get it on NuGet!
https://www.nuget.org/packages/SignalR.Client.TypedHubProxy
or

Install-Package SignalR.Client.TypedHubProxy

## LICENSE
[Apache 2.0 License](https://github.com/Gandalis/SignalR.Client.TypedHubProxy/blob/master/LICENSE.md)

## Example
### Prepare interfaces
#### IChatEvents
This interface will be used by the server to call methods from the client.
First of all we have to declare the interfaces:

```csharp
namespace Sample.Shared
public interface IServerHub
{
public interface IChatEvents
{
void NewMessage(string msg);
}
void DoSomething();
void DoSomethingWithParam(int id);
int DoSomethingWithParamAndResult(int id);
}
```
#### IChatHub
This interface will be implemented by the serverhub. The client will use this interface also to call these defined interface methods on the server.
```csharp
using System.Threading.Tasks;

namespace Sample.Shared
public interface IClientContract
{
public interface IChatHub
{
void SendMessage(string msg);
int GetConnectedClients();
}
void SomeInformation();
void SomeInformationWithParam(int id);
}
```
### The Hub
#### ChatHub
This is the chathub inside of the server, which implements IChatHub and uses IChatEvents.
```csharp
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Sample.Shared;

namespace Sample.Server
After that, we have to implement the ServerHub which implements IServerHub and uses IClientContract:

```csharp
public class ServerHub : Microsoft.AspNet.SignalR.Hub<IClientContract>, IServerHub
{
public class ChatHub : Hub<IChatEvents>, IChatHub
public void DoSomething()
{
private static int _connectedClients;

static ChatHub()
{
new Timer(BroadcastMessage, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
}

public override Task OnConnected()
{
++_connectedClients;
return base.OnConnected();
}

public override Task OnDisconnected(bool stopCalled)
{
--_connectedClients;
return base.OnDisconnected(stopCalled);
}

/// <summary>
/// Interface implementation of IChatHub.
/// This method can be called from a client.
/// </summary>
/// <param name="msg">The chat message.</param>
/// <returns></returns>
public void SendMessage(string msg)
{
Clients.All.NewMessage("CLIENT > " + msg);
}

public int GetConnectedClients()
{
return _connectedClients;
}

private static void BroadcastMessage(object state)
{
IHubContext<IChatEvents> hubContext =
GlobalHost.ConnectionManager.GetHubContext<ChatHub, IChatEvents>();
hubContext.Clients.All.NewMessage(string.Format("SERVER > Hello client {0}", DateTime.Now));
}
System.Console.WriteLine("DoSomething called.");
}
}
```
### The Client
### Program.cs
This is the chatclient.
```csharp
using System;
using Microsoft.AspNet.SignalR.Client;
using Sample.Shared;

namespace Sample.Client
{
internal class Program
public void DoSomethingWithParam(int id)
{
System.Console.WriteLine("DoSomethingWithParam called.");
}

public int DoSomethingWithParamAndResult(int id)
{
private static void Main()
{
// Create the connection
var connection = new HubConnection("http://localhost:1337/signalr");

// Create the hubproxy
var hubProxy = connection.CreateHubProxy<IChatHub, IChatEvents>("chatHub");

// Subscribe on the event IChatEvents.NewMessage.
// When the event was fired through the server, the static method Program.NewMessage(string msg) will be invoked.
hubProxy.SubscribeOn<string>(hub => hub.NewMessage, NewMessage);

// Start the connection
connection.Start().Wait();

// Call the method IChatHub.GetConnectedClients() on the server and get the result.
int clientCount = hubProxy.Call(hub => hub.GetConnectedClients());
Console.WriteLine("Connected clients: {0}", clientCount);

// Call the method IChatHub.SendMessage with no result.
hubProxy.Call(hub => hub.SendMessage("Hi, i'm the client."));
Console.ReadKey();
connection.Stop();
}

/// <summary>
/// This method can be called from the server.
/// </summary>
/// <param name="msg">The incoming chat message.</param>
public static void NewMessage(string msg)
{
Console.WriteLine(msg);
}
System.Console.WriteLine("DoSomethingWithParamAndResult called.");
return id;
}
}
```
At the client, we have to set up the connection:

```csharp
var hubConnection = new Microsoft.AspNet.SignalR.Client.HubConnection("http://localhost:1337/signalr");
```
### Invocations

The next part is the interesting one - The usage of the strongly typed HubProxy.
To understand exactly what the TypedHubProxy does, here an example of how it is used normally:

```csharp
Microsoft.AspNet.SignalR.Client.IHubProxy hubProxy = hubConnection.CreateHubProxy("serverHub");
hubProxy.Invoke("DoSomething", new object[0]);
```
The part of the Invoke had really bugged me out was the lack of strongly typed invocation.
So SignalR.Client.TypedHubProxy enables strongly typed invocation and much more. The following code sample shows you exactly what can it be used for:
```csharp
IHubProxy<IServerHub, IClientContract> hubProxy = hubConnection.CreateHubProxy<IServerHub, IClientContract>("serverHub");

// Here you can define the method which should be called - strongly typed.
hubProxy.Call(hub => hub.DoSomething());

// For methods with parameters, just handover the parameter.
hubProxy.Call(hub => hub.DoSomethingWithParam(5));

// For methods with a result, you can receive it as expected.
int result = hubProxy.Call<int>(hub => hub.DoSomethingWithParamAndResult(5));
```
Async calls are also possible:
```csharp
hubProxy.CallAsync(hub => hub.DoSomething());
hubProxy.CallAsync(hub => hub.DoSomethingWithParam(5));
System.Threading.Tasks.Task<int> asyncResult = hubProxy.CallAsync(hub => hub.DoSomethingWithParamAndResult(5));
int result = asyncResult.Result; // or just: int result = hubProxy.CallAsync(hub => hub.DoSomethingWithParamAndResult(5)).Result;
```

### Subscriptions
The old way:
```csharp
Microsoft.AspNet.SignalR.Client.IHubProxy hubProxy = hubConnection.CreateHubProxy("serverHub");
hubProxy.On<int>("SomeInformationWithParam", i => System.Console.WriteLine("Got new information: {0}", i));
```

And the new way with SignalR.Client.TypedHubProxy:
```csharp
IHubProxy<IServerHub, IClientContract> hubProxy = hubConnection.CreateHubProxy<IServerHub, IClientContract>("serverHub");
hubProxy.SubscribeOn(hub => hub.SomeInformation, () => System.Console.WriteLine("Got some new information."));
hubProxy.SubscribeOn<int>(hub => hub.SomeInformationWithParam, i => System.Console.WriteLine("Got new information: {0}", i));
```

It's also possible to define a condition on the subscription, so that you will be only called if the condition is true:
```csharp
IHubProxy<IServerHub, IClientContract> hubProxy = hubConnection.CreateHubProxy<IServerHub, IClientContract>("serverHub");
hubProxy.SubscribeOn<int>(hub => hub.SomeInformationWithParam, i => i == 5, i => System.Console.WriteLine("Got new information where data == 5"));
```

### Observable
```csharp
System.IObservable<int> observableResult = hubProxy.Observe<int>(hub => hub.SomeInformationWithParam);
```

0 comments on commit 1dd6300

Please sign in to comment.