Signalr core client - call server methode from Razor component - signalr

How can I send a message to my server from, let's say a Razor component?
The situation:
I have a working SignalR (Core) connection with my server.
My client code:
public class StartMySignalR
{
HubConnection connection;
public async void StartSignalRHub()
{
connection = new HubConnectionBuilder()
.WithUrl(new Uri("https://myurl.my/LogOnHub"))
.WithAutomaticReconnect()
.Build();
connection.On<string>("ReceiveMessage", (message) =>
{
//Do some stuff
ii.InsertIntoLog("INFO", "SignalR ID = " + message);
});
//Start SignalR client
await connection.StartAsync();
//Send message to server (test connection).
await connection.InvokeAsync("WelcomeMessage", connection.ConnectionId);
I send a test message to my server, that works fine. I can also send a message back from my server,.. so far so good. But now I want to do that from a Razor component in my OnInitializedAsync() Task. So when my page loads, the test message is sent to my server. There I am stuck. When I try to send the message from my Razor component I receive an error (System.NullReferenceExeption - Object reference not set to an instance of an object) -> connection was null error.
Can somebody put me in the right direction?

When I set the Hubconnection to static it works.
public static HubConnection connection;

Related

Java gRPC: exception from client to server

Is it's possible to throw an exception from the client to the server?
We have an open stream from the server to the client:
rpc addStream(Request) returns (stream StreamMessage) {}
When i try something like this:
throw Status.INTERNAL.withDescription(e.getMessage()).withCause(e.getCause()).asRuntimeException();
I got the exception in the StreamObserver.onError on the client, but there is no exception on the server-side.
Servers can respond with a "status" that the stub API exposes as a StatusRuntimeException. Clients, however, can only "cancel" the RPC. Servers will not know the source of the cancellation; it could be because the client cancelled or maybe the TCP connection broke.
In a client-streaming or bidi-streaming call, the client can cancel by calling observer.onError() (without ever calling onCompleted()). However, if the client called onCompleted() or the RPC has a unary request, then you need to use ClientCallStreamObserver or Context:
stub.someRpc(request, new ClientResponseObserver<Request, Response>() {
private ClientCallStreamObserver<Request> requestStream;
#Override public void beforeStart(ClientCallStreamObserver<Request> requestStream) {
this.requestStream = requestStream;
}
...
});
// And then where you want to cancel
// RequestStream is non-thread-safe. For unary requests, wait until
// stub.someRpc() returns, since it uses the stream internally.
// The string is not sent to the server. It is just "echoed"
// back to the client's `onError()` to make clear that the
// cancellation was locally caused.
requestStream.cancel("some message for yourself", null);
// For thread-safe cancellation (e.g., for client-streaming)
CancellableContext ctx = Context.current().withCancellation();
StreamObserver requestObserver = ctx.call(() ->
stub.someRpc(new StreamObserver<Response>() {
#Override public void onCompleted() {
// The ctx must be closed when done, to avoid leaks
ctx.cancel(null);
}
#Override public void onError() {
ctx.cancel(null);
}
}));
// The place you want to cancel
ctx.cancel(ex);

Working with Groups in SignalR core

I create Hub class, when new user connect call function OnConnected:
public class ReportChat : Hub
{
public async Task OnConnected()
{
string name = Context.User.Identity.Name;
await Groups.AddAsync(Context.ConnectionId, name);
}
}
But when connected second user, or sometimes, when I refresh page SignalR generate error on frontend: No Connection with that ID.
Using transport protocol: signalR.TransportType.LongPolling
connection = new signalR.HubConnection("/ReportJson", { transport: signalR.TransportType.LongPolling });
connection.on('SendReport',
function(data) {
console.log(data.value.name);
});
connection.start().then(() => {
connection.invoke('OnConnected');
hubConnectionEstablished = true;
});
When you refresh your page you are disconnecting and reconnecting and therefore will be generating a new connectionId for that client.
You can verify that this is happening by setting breakpoints in your OnConnected and OnDisconnected methods.

Connecting with SignalR after login or Delayed connection with SignalR

I am working with SignalR & MVC. The code that i looked up actually connects the user to the hub at startup.
[assembly: OwinStartup(typeof(Uno.Hubs.Startup))]
namespace ChatTBox
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
app.MapSignalR();
}
}
}
However, i need the user to connect to SignalR after it has successfully logged in and then keep and display the list of connected signed in user. How to do that?
This call doesn't connect the user to the hub, it simply registers the SignalR middleware (the same way you would call app.UseWebApi()). Connecting a user is initiated by the client from the client.
You can connect a client after login from the client. The example on asp.net can be modified to suit:
// login
// assuming your hub is called ChatTBoxHub
var chatTBoxHubProxy = $.connection.contosoChatHub;
// wire up the event the server can call on the client
chatTBoxHubProxy.client.addMessageToPage = function (name, message) {
console.log(name + ' ' + message);
};
// start the signalR connection
$.connection.hub.start().done(function () {
// Wire up Send button to call NewContosoChatMessage on the server.
chatTBoxHubProxy.server.register(someUniqueClientIdServer);
});
// For .Net clients:
var hubConnection = new HubConnection("http://yourUrl/");
IHubProxy chatTBoxHubProxy = hubConnection.CreateHubProxy("ChatTBoxHub");
chatTBoxHubProxy.On<Message>("addMessageToPage", message => Console.WriteLine("Message '{0}' received from {1}", message.Body, message.Name));
await hubConnection.Start();
// EDIT to add example registration in your server hub class
public void Register(string uniqueClientId)
{
hubUsers[uniqueClientId] = Context.ConnectionId; // Context is supplied by SignalR base class.
}

SignalR .NET client not firing events when network connection is lost

I have WPF application that connects to WebAPI, which runs SignalR. Everything works fine, until Internet connection is lost by client.
When it happens, SignalR does not fire any events on client side (StateChanged, Error, Reconnecting, Closed etc.)
Code is pretty straightforward
public HubConnection _hubConnection;
IHubProxy _proxy;
public async Task ConnectToHub(string hubUrl, string hubName)
{
_hubConnection = new HubConnection(HubURL);
_hubConnection.Reconnecting += hubConnection_Reconnecting;
_hubConnection.Closed += _hubConnection_Closed;
_hubConnection.StateChanged += _hubConnection_StateChanged;
proxy = hubConnection.CreateHubProxy(hubName);
await _hubConnection.Start();
}
void _hubConnection_StateChanged(Microsoft.AspNet.SignalR.Client.StateChange obj)
{
throw new NotImplementedException();
}
void _hubConnection_Closed()
{
throw new NotImplementedException();
}
void _hubConnection_Reconnectig()
{
throw new NotImplementedException();
}
SignalR version 2.2.0
Thanks for help
Try subscribing to the Error event. Depending on "how" the connection is lost, I don't think some of the other events will get fired.
_hubConnection.Error += (e=>{ ... });
Transport type on SignalR was set automatically to ServerSentEvents instead of WebSockets (Server admin didn't turn it on). Turned out that only with Websockets we can get connection-related events on .Net-client, when connection is lost.
According to http://www.asp.net/signalr/overview/getting-started/introduction-to-signalr
WebSocket is the only transport that establishes a true persistent, two-way connection between client and server.

can not use signalr sample for a console application

i was trying signalR hubs trough their sample at https://github.com/SignalR/SignalR/wiki/QuickStart-Hubs.
i managed to create an mvc 4 asp.net app using their sample for asp.net, BUT when i try to debug the console app program :
public class Program
{
public static void Main(string[] args)
{
// Connect to the service
var hubConnection = new HubConnection("http://localhost/5623");
// Create a proxy to the chat service
var chat = hubConnection.CreateHubProxy("chat");
// Print the message when it comes in
chat.On("addMessage", message => Console.WriteLine(message));
// Start the connection
hubConnection.Start().Wait();
string line = null;
while((line = Console.ReadLine()) != null)
{
// Send a message to the server
chat.Invoke("Send", line).Wait();
}
}
}
it send me an exception at hubConnection.Start().Wait(); saying {"The remote server returned an error: (500) Internal Server Error."}.
i think it has something to do with the http://localhost/5623, i tried http://localhost/5623/Home and http://localhost/5623/Home/Chat i got {"The remote server returned an error: (404) Not Found."} error instead.
How can i solve this please.
Thank you.

Resources