SignalR - How to call server function with parameter from client using hubproxy - signalr

I have my signalr running on a separate domain. We will have multiple applications using it to send and receive messages. I created the connection and hub proxy using the following code
connection = $.hubConnection("https://someurl.com", { useDefaultPath: false });
chatHub = connection.createHubProxy('chatHub');
I can get messages from the server sent to the client using the following code which works fine
chatHub.on('receiveEntityMessage', function (chatMessage) {
if (chatMessage) {
console.log(chatMessage.Message);
}
});
Now I dont know how to call server functions with parameters from the client. Can anybody please help me with this?

chatHub.invoke("MethodName", param1, param2, param3).done(function(result) {
console.log(result);
});

Since i'm not sure what is the language of your server side, i am going to provide a C# example.
C# Hub method example:
public class chatHub: Hub {
public void YourHubMehotd(int firstParam, string secondParam){
//The action of your method
}
}
JS client side:
You can call your hub method like this:
{The variable with the hub connection}.server.{the method you want to call}( {the parameters} )
Example:
chatHub.server.YourHubMehotd(1,"Example");
I recomend to create a js function to call the hub method.
function callMyHubMethod(firstParam, secondParam){
chatHub.server.YourHubMehotd(firstParam, secondParam);
}

Related

signlar hub method termination

I'd like to know if an Hub method called from js client is
executed completely also if client disconnected during execution
For example..
public virtual void Join(int userId)
{
using (var context = new HubConnectionContext(this, RoomId, userId))
{
T workflow = GetWorkflow(context);
workflow.OnUserJoin();
}
}
I can be sure that the Dispose Method of HubConnectionContext is called also if client disconnect during using block?

SignalR OnConnected Not Hitting But Still Able to Invoke Client Side Functions From Server

I have the following TestHub that does nothing but invoke a client side sayHello() function.
public class TestHub:Hub
{
public void SayHello()
{
Context.Clients.All.sayHello();
}
public override Task OnConnected()
{
//do some custom stuff
return base.OnConnected();
}
}
On the client, I have the following:
var connection = $.hubConnection('http://localhost:12345/signalr');
var proxy = connection.createHubProxy('TestHub');
proxy.on('sayHello',function(){
console.log('sayHello fired');
})
connection.start().done(function(){
console.debug('Connected');
})
When I call SayHello() on my TestHub the client prints out the following perfectly fine
sayHelloFired
and when the proxy first loads, it prints the following to the console perfectly fine.
Connected
However, if I throw a breakpoint in the OnConnected() method on TestHub, then it does not hit.
All the posts discussing similar problems suggest that their is no handlers being subscribed on the client side, but that is not the case here. How could this be working and OnConnected() is never fired?
Your code didn't compile for me because of the
Context.Clients.All.sayHello();
Line. Context here tries to refer to Hub.Context which is an HubCallerContext class. I think you want to refer to Hub.Clients which is an IHubCallerConnectionContext.
I replaced that line to
Clients.All.sayHello();
And my breakpoint got invoked.
However I am surprised you made it run and got messages on console.
BTW You are right about that, when using javascript clients, if there is no subscription to any event in the hub, the OnConnected methond won't be invoked.
But that is not the case here.

SignalR and Hub Persistance

I am trying out SignalR, and i don't quite understand how to call methods from my client in a way that it calls the same hub.
i have two methods in my hub:
private ctlDataManager myManager;
public void StartConnection()
{
myManager = new ctlDataManager("test");
myManager.UpdateItemEvent += myManager_UpdateItemEvent;
myManager.Connect();
}
public void StopConnection()
{
myManager.Disconnect();
}
And in my client i try to call them like this:
var notificationHub = $.connection.notificationHub;
$.connection.hub.start()
.done(function (state) {
$("#submit").click(function (e) {
e.preventDefault();
notificationHub.server.startConnection();
return false;
});
$("#stop").click(function (e) {
e.preventDefault();
notificationHub.server.stopConnection();
return false;
});
});
Now when i click on the start button it works fine it starts it and receives data too.
But when i click the stop button it throws an instance of an object error.
It appears that 'myManager' is null. It's almost as a new hub were open. Naturally i need it to be the same one as i need to close the connection.
How can i do that?
From my understanding, the server-side hub class is not persisted. Therefore, the myManager object is created with each method call from a client. My advice would be to declare myManager elsewhere in your application that you can assure 100% up-time, and have your server-side hub methods communicate with it that way.
One way for you to verify this is to debug the constructor of your hub class. You will notice that it is called for every client->server-side method call.

SignalR Broadcast from Controller not working

I'm using the latest version of SignalR (1.0.1). I am trying to broadcast from my controller to the hub and having a few issues:
My client does not seem to be getting messages.
It doesn't seem that my hub context even has an 'addMessage' defined:
My hub:
public class SignalRPriceHub : Hub
{
public void sndMessage(string msg)
{
Clients.All.addMessage(msg + "****");
}
}
Javascript client:
<script src="#Url.Content("~/Scripts/jquery.signalR-1.0.1.min.js")"></script>
<script src="~/signalr/hubs"></script>
.....
var myHub = $.connection.signalRPriceHub;
myHub.client.addMessage = function (message) {
alert(message);
};
Controller:
var context = GlobalHost.ConnectionManager.GetHubContext<SignalRPriceHub>();
context.Clients.All.addMessage("TestOutsideMessage!!!");
A few things I noticed:
1. My hub context doesn't seem to have an 'addMessage'
{"'Microsoft.AspNet.SignalR.Hubs.ClientProxy' does not contain a definition for 'addMessage'"} System.Exception {Microsoft.CSharp.RuntimeBinder.RuntimeBinderException}
If I run the following code from the same file as my client code above, I do get a message.
var myHub = $.connection.signalRPriceHub;
$.connection.hub.start(function () {
myHub.server.sndMessage("Hello World!");
});
Can anyone shed some light as to what might be happening? Thanks all!
I'll go over the faults in your initial application which shed light to why your second bullet point makes it all work.
In your javascript client you must start the connection:
$.connection.hub.start();
You must then request the message on your hub by calling the sndMessage command:
$.connection.hub.start().done(function() {
myHub.server.sndMessage("Hello world");
});
The reason why you do not see an addMessage function on your hub context is because the hub context .Clients.All is dynamic.
One last note, in order to make the sample work you also need to make sure that in your Application_Start you have RouteTable.Routes.MapHubs(); . I assume you already have this since once you add the connection start that everything works.

invoking client script from server - SignalR

I'm using SignalR in my mvc4 web application.
I have a class inheriting from HUB
[HubName("Chat")]
public class ChatHub : Hub ,IDisconnect
{
private void CallMessage(string message)
{
Clients.MessagesRecieved(message);
}
....
In my client js file I wrote
$(function () {
globalChatHub = $.connection.chat;
$.extend(globalChatHub, { MessagesRecieved: function (data) {
alert(data);
}
});
the question is ,
Is it possible to invoke the client side script "MessagesRecieved function" from a code in my HomeController.cs
let's say somthing like that :
public class HomeController : Controller
{
public ActionResult Index()
{
// this is a test
ChatHub h = new ChatHub();
h.CallMessage("hellow");
}
Sure,
You can call it the same way you call client code:
//Define the client method:
globalChatHub.hello = function {alert('hello');}
in the server code just write:
ChatHub h = new ChatHub();
h.Client.hello();
the name of the method is case sensitive.
more info in this link SignalR quick start
You can have a the Hub context for your ChatHub with this code:
var context = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
Then you can call any method you would like on your ChatHub or you can call client methods directly. E.g.:
context.Clients.All.MessagesRecieved("test");
Give it a try. Hope this helps.
In mvc controller, I use following code to call methods in hub
DefaultHubManager hd = new DefaultHubManager(GlobalHost.DependencyResolver);
var hub = hd.ResolveHub("ChatHub") as ChatHub;
hub.Echo(HttpContext.Session.SessionID, "Hello Echo");
In the hub implementation, I prefer to keep the implementation to call clients in Hub to make the code cohesive.
public void Echo(string sessionId, dynamic data)
{
var context = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
context.Clients.All.ClientSideMethod(..)
}

Resources