SignalR javascript callback not working - asp.net

I have hub class:
public class ChatHub : Hub
{
// Send message
public void Send(string message)
{
Clients.addMessage(DateTime.Now.ToString("HH:mm:ss") + " " + message);
}
}
And javascript:
// Proxy created on the fly
var chat = $.connection.chatHub;
// Declare a function on the chat hub so the server can invoke it
chat.addMessage = function(message) {
alert("message:" + message);
$('#chat').append('<div>' + message + '</div>');
};
$("#sendButton").click(function () {
// Call the chat method on the server
chat.send($('#message').val())
.done(function () {
console.log('Success!')
})
.fail(function (e) {
console.warn(e);
})
});
// Start the connection
$.connection.hub.start();
All conection are fine:
If I use breakpoint in here Clients.addMessage(DateTime.Now.ToString("HH:mm:ss") + " " + message); everything is fine.
But i don't get callback on javascript function.
alert("message:" + message); never executes

Did you add the client side Signalr hub?
<script src="/signalr/hubs" type="text/javascript"></script>

Related

SignalR Private Chat Not Returning Data

I implemented SignalR to my project. But I have problem sending private message. I am sending 'toConnectionID' from page.
ChatHub.cs
public void LoadPrivateMessages(string toUserName,string toConnectionID)
{
var chatHub = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
string fromUserName = Context.QueryString["userName"].ToString();
string fromConnectionID = Context.ConnectionId;
List<ChatMessageDetail> currentMessages = cachePrivateMessages.Where(x => x.ToUserName == toUserName && x.FromUserName == fromUserName && x.ToConnectionID==toConnectionID && x.FromConnectionID==fromConnectionID).ToList();
chatHub.Clients.Client(toConnectionID).privateMessagesHistory(currentMessages);
}
My currentMessages list is filling. I am OK here. But I can't take messages to page.
Javascript
chatHub.client.privateMessagesHistory = function (data) {
console.log(data);
};
My console screen is null after this JavaScript code.
Edit :
That is my connection code in document.ready function. Second is sending information about receiver.
var chatHub = $.connection.chatHub;
$.connection.hub.qs = { "userName": "#Session["userName"]" };
$.connection.hub.start().done(function () {
console.log("Connection OK !");
});
$(document).on('click','.onlineUser', function () {
var userName = $(this).attr('id');//That is which user to send(Receiver)
var toConnectionID = $(this).attr('connectionID');
chatHub.server.loadPrivateMessages(userName, toConnectionID);
$('.privateMessagediv').show();
$('.userName').html("");
$('.userName').append("<h4>" + userName + "</h4>");
$('.btnSendingPrivateMessage').attr('id', userName);
$('.btnSendingPrivateMessage').attr('connectionid', toConnectionID);
chatHub.client.privateMessagesHistory = function (data) {
$('#privateChatBox').append(data);
};
});
Edit 2 :
I solved issue.
chatHub.Clients.Client(fromConnectionID).privateMessagesHistory(currentMessages);
instead of
chatHub.Clients.Client(toConnectionID).privateMessagesHistory(currentMessages);
My original suspicion was with the toConnectionId, but after examining your privateMessageHistory callback registration, it's more likely a timing issue.
You need to setup the client callback before the hub .start().
From Microsoft:
Normally you register event handlers before calling the start method
to establish the connection. If you want to register some event
handlers after establishing the connection, you can do that, but you
must register at least one of your event handler(s) before calling the
start method
There's no need to place your callback registration in the click event.
var chatHub = $.connection.chatHub;
$.connection.hub.qs = { "userName": "#Session["userName"]" };
// callback first
chatHub.client.privateMessagesHistory = function (data) {
$('#privateChatBox').append(data);
};
// start the hub connection - note chatHub is different from your .hub
chatHub.start().done(function () {
console.log("Connection OK !");
});

how to respond from client to server and server to client using signalr

I am new to signalr,
I have gone through a number of tutorials where I have seen the chat room application where server has been configured on console app and client on javascript, as you open the multiple instances of browsers you can chat between them.
My question is how to chat between server to client rather than between clients.
lets say I build a server on winform. On that winform I have datagridview which shows me the number of clients connected to server and I want to send a message to client #2 , then the client #2 will also reply me which I will show in a textbox on winform.
My Client Code:
<script type="text/javascript">
$(function () {
$.connection.hub.url = "http://localhost:8080/signalr";
var chat = $.connection.myHub;
// Create a function that the hub can call to broadcast messages.
chat.client.addMessage = function (name, message) {
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
$('#displayname').val(prompt('Enter your name:', ''));
$('#message').focus();
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
chat.server.send($('#displayname').val(), $('#message').val());
$('#message').val('').focus();
});
});
});
</script>
Myhub.cs:
public class MyHub : Hub
{
public void Send(string name, string message)
{
Clients.All.addMessage(name, message);
}
public void getname(string name)
{
}
public override Task OnConnected()
{
UserHandler.ConnectedIds.Add(Context.ConnectionId);
string RemoteIpAddress = Context.Request.GetRemoteIpAddress();
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
UserHandler.ConnectedIds.Remove(Context.ConnectionId);
return base.OnDisconnected(stopCalled);
}
public void acknowledgment(string ack)
{
Clients.Caller.acknowledgment(ack);
}
}
Code seems good. try to add following code in startup.cs
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true
};
map.RunSignalR(hubConfiguration);
});

Call SignalR Client Method on Startup

I want to call a client side method from my SignalR hub class only once, when the client first loads up the webpage. How would I go about doing this?
In your BlahBlahHub class, you have access to all of the connection methods that you do on the Client. Hint: Look at the base Hub class.
With that being said, here's what the code would look like:
Hub
[HubName("messageHub")]
public class MessageHub : Hub
{
public override Task OnConnected()
{
Clients.Caller.alertUser(88);
return base.OnConnected();
}
}
Client
var sender = $.connection.messageHub;
$.connection.hub.start().done(function () {
}).fail(function (reason) {
console.log("SignalR connection failed: " + reason);
});
sender.client.alertUser = function (test) {
alert(test);
};

SignalR notification from server to client

I want to push a notification from my server to client. I've tried the chat tutorial found here but this just sends chat messages from one client to client
What I want is a button whose onClick method is running at server. Once, I click this button, notifications (a string message) must be sent to all clients.
My Hub class is
public class NotificationsHub : Hub
{
public void SendNotification(string author, string message)
{
Clients.All.broadcastNotification(author, message);
}
}
and in the button click, I try this
var context = GlobalHost.ConnectionManager.GetHubContext<NotificationsHub>();
context.Clients.All.SendNotification("Admin", "stop the chat");
But still, I'm not able to notify the clients. Nothing is happening. What am I doing wrong??
My JS at client web page to notify is like this
<script type="text/javascript">
$(function () {
// Declare a proxy to reference the hub.
var notifications = $.connection.notificationsHub;
// Create a function that the hub can call to broadcast messages.
notifications.client.broadcastNotification = function (name, message) {
alert(name + " says '" + message + "'");
};
You need to call broadcastNotification in your button click function, like below:
var context = GlobalHost.ConnectionManager.GetHubContext<NotificationsHub>();
context.Clients.All.broadcastNotification("Admin", "stop the chat");
Also, you need to start the hub by adding $.connection.hub.start(), your JS file should be like:
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.signalR-2.0.1.js"></script>
<script src="/signalr/hubs"></script>
<script type="text/javascript">
$(function () {
var notifications = $.connection.notificationsHub;
notifications.client.broadcastNotification = function (name, message) {
alert(name + " says '" + message + "'");
$.connection.hub.start();
};
</script>

Call specific clients in SignalR

I'm developing a SignalR application in which set of .NET console clients connecting to a web server. How can I call a specific client from the server using SignalR.
In the current application I did, when I click button from the server side. It triggers all the Console clients. But what I want to trigger is keeping all client information on server.html and call specific client.
Currently this is my console application
class Program
{
static void Main(string[] args)
{
var connection = new Connection("http://localhost:65145/printer");
//Establishing the connection
connection.Start().ContinueWith(task =>
{
if (task.IsFaulted)
{
Console.WriteLine("Failed to start: {0}", task.Exception.GetBaseException());
}
else
{
Console.WriteLine("Success! Connected with client connection id {0}", connection.ConnectionId);
}
});
//Reciveing data from the server
connection.Received += data =>
{
Console.WriteLine("Receiving print request from server");
Console.WriteLine(data);
};
Console.ReadLine();
}
}
This is the server side.
server html which calls clients
<script type="text/javascript">
$(function () {
var connection = $.connection('/printer');
connection.received(function (data) {
//$('#messages').append('<li>' + data + '</li>');
});
connection.start().done(function() {
$('#print').click(function () {
var printThis = { value: 113, reportId: 'Report', printer: '3rd Floor Lazer Printer', Copies: 1 };
connection.send(JSON.stringify(printThis));
});
});
});
</script>
Global.asax
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs();
RouteTable.Routes.MapConnection<MyConnection>("printer", "/printer");
}
The documentation shows how to do this https://github.com/SignalR/SignalR/wiki/PersistentConnection#sending-to-a-specific-connection

Resources