I want to access session value on my hub class
My jquery code is as below
var con = $.connection.MyHub;
$.connection.hub.start().done(function () {
con.server.send().done(function (data) {
displayservices(data);
})
})
con.client.addmessege = function (data) {
displayservices(data);
//alertSound();
};
My hub class is as bellow
public Class MyHub : Hub
{
public void send(string msg)
{
client.all.addmessage(msg)
}
}
How can I access session value in my hub class
You can get the current session from HttpContext, like this:
var sessionVar = HttpContext.Current.Session["SessionVar"];
Related
I'm not too familiar with signalr2 on asp.net-core pardon me, am trying to create a POC on how to implement a real-time CRUD application with admin and client using signalr2, but am having issues with signalr data push, I keep getting NullReferenceException: Object reference not set to an instance of an object. on this line await Clients.All.SendAsync("BroadcastData", data);
Below is how I setup my Hub using some online examples I looked-up:
public class OddPublisher : Hub
{
private readonly IOddServices _oddService;
public OddPublisher(IOddServices oddService)
{
_oddService = oddService;
}
public async Task BroadcastData()
{
var data = _oddService.ClientQueryOdds();
await Clients.All.SendAsync("BroadcastData", data); //breaks here
}
}
and this is triggered by admin, on submiting and saving the data sucessfully I call the BroadcastData()
public class BaseController : Controller
{
public IOddServices _oddService;
public readonly OddPublisher _publisher;
public BaseController(IOddServices oddService, )
{
_oddService = oddService;
_teamService = teamService;
_publisher = new OddPublisher(oddService);
}
[HttpPost]
public async Task<IActionResult> odd_entry(CreateOdd dto)
{
//somecode here...
var results = _validator.Validate(dto);
if(!results.IsValid)
{
results.AddToModelState(ModelState, null);
return View(dto);
}
_oddService.CreateOddAndTeam(dto);
await _publisher.BroadcastData(); //Breaks
return RedirectToAction(nameof(index));
}
}
Folled all the instructions as adviced in Microsoft Asp.Net Core Signalr Documentation, my Startup has all required sevices added.
here is the client and the JS file,
"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("/oddPublisher").build();
connection.on("BroadcastData", data => {
console.table(data);
//getAll();
})
connection.start().then(function () {
getAll();
}).catch(function (err) {
return console.error(err.toString());
});
function getAll() {
var model = $('#dataModel');
$.ajax({
url: '/home/GetLatestOddData',
contentType: 'application/html ; charset:utf-8',
type: 'GET',
dataType: 'html',
success: function (result) { model.empty().append(result); }
});
}
Need some help here guys, I still don't know what am doing wrong, I'll really appreciate if I can get any help on this.
Thank you in advance.
It turns out I needed to Inject the IHubContext into my hubs to have access to the clients.
I am learning SignalR and it pretty simple. However, I am having a problem sending Messages from Server to client.
My Hub class is as follows:
public class UpdateHub : Hub
{
private readonly UpdateBroadcast _broadcaster;
public UpdateHub() : this(UpdateBroadcast.Instance) { }
public UpdateHub(UpdateBroadcast broadCaster)
{
_broadcaster = broadCaster;
}
}
And I am calling this hub in my broadcaster class like this:
public class UpdateBroadcast
{
private readonly static Lazy<UpdateBroadcast> _instance = new Lazy<UpdateBroadcast>(
() => new UpdateBroadcast(GlobalHost.ConnectionManager.GetHubContext<UpdateHub>()));
private IHubContext _context;
private UpdateBroadcast(IHubContext context)
{
_context = context;
}
public static UpdateBroadcast Instance
{
get { return _instance.Value; }
}
public void UpdatePost(Post post)
{
_context.Clients.All.updatePost(post);
}
}
In my MVC Controller I am calling the UpdatePost method:
public JsonResult AddPost(Post post)
{
UpdateBroadcast broadcaster = UpdateBroadcast.Instance;
Post result = dbFunctions.AddPost(post);
broadcaster.UpdatePost(post);
return Json(new { success = result != null }, JsonRequestBehavior.DenyGet);
}
When I debug the code, I can see that UpdatePost is executed but there is no activity on the client side. My client-side function is like this:
$(function () {
var update = $.connection.updateHub;
update.client.updatePost = function (data) {
alert("called update post");
};
});
I don't seem to understand what is causing this.
Please check below 2 links. I got really helpful with successfully implementation of signalR. Hopefully, this links help you.
https://github.com/vgheri/ChatR
http://www.codeproject.com/Articles/524066/SignalR-Simple-Chat-Application-in-Csharp
In our application I want to have a "realtime" grid of notifications that the user can monitor. That grid is a KendoUI grid with SignalR-transport and is read-only. So the only hub method defined is a Read method.
This is my hub that is hooked up to the KendoUI grid.:
[HubName( "NotificationsHub" )]
public class NotificationsHub : Hub
{
public IApplicationSupportService Service { get; set; } //injeccted with Autofac
public NotificationsHub()
{
}
public IEnumerable<EventViewModel> Read()
{
var events = from e in Service.FindEvents()
select new EventViewModel
{
EventId = e.EventId,
Text = e.Text,
CreatedOn = e.CreatedOn
};
return events;
}
}
I also have a NServiceBus message handler that is supposed to call a client side method called "addEventToPage". The notification handler receives a nevent from the service bus and is supposed to call all clients to update their grid.
This is the message handler on the server side, that uses a singleton helper to call the hub's clients via context.Clients.All.addEventToPage():
//NServiceBus message handler subscribes to an event, then calls clients
public class NotificationsHandler : IHandleMessages<IBusinessEventReceived>
{
public void Handle( INewEventWasSaved message )
{
NotifyTicker.Instance.UpdateClient( message.EventId, message.Text );
}
}
public class NotifyTicker
{
// Singleton instance
private static readonly Lazy<NotifyTicker> _instance = new Lazy<NotifyTicker>(
() => new NotifyTicker( GlobalHost.ConnectionManager.GetHubContext<NotificationsHub>() ) );
private IHubContext _context;
private NotifyTicker( IHubContext context )
{
_context = context;
}
public static NotifyTicker Instance
{
get { return _instance.Value; }
}
public void UpdateClient( int eventId, string text )
{
_context.Clients.All.addNewEventToPage( eventId, text );
}
}
The client code:
<script>
var hubProxy;
var hubStart;
$(function () {
var connection = $.connection;
$.connection.hub.logging = true;
hubProxy = connection.NotificationsHub;
//this function is called by message handler on server
hubProxy.client.addNewEventToPage = function (eventId, text) {
console.log(eventId + ' ' + text);
};
hubStart = $.connection.hub.start()
.done(function () { console.log('Now connected, connection ID=' + $.connection.hub.id); })
.fail(function () { console.log('Could not Connect!'); });
$("#grid").kendoGrid({
editable: false,
columns: [
{ field: "Text" }
],
dataSource: {
type: "signalr",
autoSync: true,
schema: {
model: {
id: "EventId",
fields: {
"EventId": { editable: false, nullable: true },
"Text": { type: "string" }
}
}
},
transport: {
signalr: {
promise: hubStart,
hub: hubProxy,
server: {
read: "read"
},
client: {
read: "read"
}
}
}
}
});
});
</script>
As you can see I am adding the "addEventToPage" method BEFORE the hub proxy starts. But the method is not called, period.
Originally, that method was supposed to add a EventViewModel to the KendoUI grid's datasource like so:
dataSource.add({
EventId: eventId,
Text: text
});
But that didn't work. It can't even write to the console.
The connection is established successfully, with web sockets. I can confirm that in the Chrome console output.
What am I missing?
Is there maybe a better way to update the grid without a customer client -side function? Maybe I can tell teh grid to Re-Read?
I make an asp.net Messenger WebProject using XSockes.
When run this project onopen and onconnected events its happens.
but wen send message does not work.
what is my fault?
Startup Code:
[assembly: OwinStartupAttribute(typeof(XsocketTest1.Startup))]
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseXSockets(true);
}
}
Starter Code:
[assembly: PreApplicationStartMethod(typeof(XsocketTest1.Starter), "Start")]
namespace XsocketTest1
{
public class Starter
{
private static IXSocketServerContainer container;
public static void Start()
{
container = XSockets.Plugin.Framework.Composable.GetExport<IXSocketServerContainer>();
container.Start();
}
}
}
Controller Code:
public class Chat : XSocketController
{
public string UserName { get; set; }
public void ChatMessage(string message)
{
this.InvokeToAll(message, "chatmessage");
}
}
And JavaScript Code:
$(function () {
try{
var controler = new XSockets.WebSocket('ws://localhost:34853', ['chat']);
var conn = controler.controller('chat');
conn.onopen = function () {
}
conn.onconnected = function () {
console.log('socket connected');
conn.controller('chat').chatmessage = function (data) {
console.log(data.Text);
};
};
}
catch(e)
{
alert(e);
}
$(document).ready(function () {
$("#btnSend").click(function () {
try{
conn.invoke('chatmessage', {
Text: 'Calling chatmessage on server and passing a part of the complex object'
});
}
catch(e)
{ alert(e);}
});
});
});
The code looks pretty weird...
Take a look here: http://xsockets.net/docs/4/installing-xsocketsnet
And you will see that you have duplicate startup classes... All you need is the "usexsockets" part if you use owin and win8+ (also mentioned in the docs).
Your JavaScript might work but is very confusing since it seems like you have misunderstood the difference between a connection and a controller in xsockets.
I have created a simple SignalR hub inside a console application:
class Program
{
static void Main(string[] args)
{
using (WebApp.Start<Startup>("http://localhost:1968"))
{
Console.WriteLine("Server running!");
Console.ReadLine();
}
}
}
public static class UserHandler
{
public static HashSet<string> ConnectedIds = new HashSet<string>();
}
[HubName("echo")]
public class EchoHub : Hub
{
public void Say(string message)
{
Trace.WriteLine("hub: "+message);
Clients.All.AddMessage(message);
}
public override Task OnConnected()
{
UserHandler.ConnectedIds.Add(Context.ConnectionId);
return base.OnConnected();
}
public override Task OnDisconnected()
{
UserHandler.ConnectedIds.Remove(Context.ConnectionId);
return base.OnDisconnected();
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
When I try to connect this from a Silverlight App, it succeeds:
static Microsoft.AspNet.SignalR.Client.HubConnection signalR { get; set; }
public static Microsoft.AspNet.SignalR.Client.IHubProxy signalRhub { get; set; }
public static void StartSignalR()
{
var url = "http://localhost:1968";
signalR = new Microsoft.AspNet.SignalR.Client.HubConnection(url);
signalR.Received += signalR_Received;
signalRhub = signalR.CreateHubProxy("echo");
signalR.Start().Wait();
signalRhub.Invoke("Say", "hub invoked");
}
My next step is to connect the SignalR hub from jquery:
<script src="../Scripts/jquery-1.6.4.js"></script>
<script src="../Scripts/jquery.signalR-2.1.0.js"></script>
<script>
$(function ()
{
var connection = $.hubConnection("http://localhost:1968");
connection.start()
.done(function () {
console.log('connected');
connection.send("success?");
})
.fail(function (a) {
console.log('not connected'+a);
});
});
</script>
When I try to run this script, it gives the error:
"XMLHttpRequest cannot load localhost:1968/signalr/negotiate?clientProtocol=1.4&_=1404978593482. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin <code>http://localhost:55282</code> is therefore not allowed access."
Why can I connect to the hub from my Silverlight page (hosted in localhost:3926)
and fails it when I run the jquery script (hosted in localhost:55282)?
What can I do to get a working connection between my jQuery and SignalR hub?
Change
$(function ()
{
var connection = $.hubConnection("http://localhost:1968");
connection.start()
.done(function () {
console.log('connected');
connection.send("success?");
})
.fail(function (a) {
console.log('not connected'+a);
});
});
to
$(function ()
{
var connection = $.hubConnection("http://localhost:1968");
var hub = connection.createHubProxy("echo");
hub.on("AddMessage", Method);
connection.start({ jsonp: true })
.done(function () {
console.log('connected');
hub.say("success?");
})
.fail(function (a) {
console.log('not connected'+a);
});
});
function Method(messageFromHub)
{
alert(messageFromHub);
}
and
class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
to
class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR(new HubConfiguration() { EnableJSONP = true });}
}
It should do.
app.MapSignalR(new HubConfiguration() { EnableJSONP = true });}
and
connection.start({ jsonp: true })
Will allow cross site request
RPC on Server in SignalR with createHubProxy():
Thanks to the answer from Vishal Ravlani
But for me
hub.say("success?");
doesn't work! (Does it work for you?)
I have to write:
hub.invoke('say','success?');
And SignalR has automatically detected CrossOrigin on Client.
On Server I have used:
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR();
});
which was described on: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client#crossdomain