如何使用 signalR c# MVC 接收特定于用户的消息?
How to receive message for user specific using signalR c# MVC?
我有一个 MVC 应用程序。
我已经实现了 singalR 来接收实时通知,但是如何只获取用户特定的通知。
NotificationSend.cs
public class NotificationSend : Hub
{
private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationSend>();
public static ConcurrentDictionary<string, MyUserType> MyUsers = new ConcurrentDictionary<string, MyUserType>();
public override Task OnConnected()
{
MyUsers.TryAdd(Context.ConnectionId, new MyUserType() { ConnectionId = Context.ConnectionId });
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
MyUserType garbage;
MyUsers.TryRemove(Context.ConnectionId, out garbage);
return base.OnDisconnected(stopCalled);
}
public static void SendToUser(string messageText)
{
hubContext.Clients.Client(MyUsers.Keys.ToList().FirstOrDefault()).Notification(messageText);
}
public static void StopLoader(string messageText)
{
hubContext.Clients.Client(MyUsers.Keys.ToList().FirstOrDefault()).Stoploader(messageText);
}
}
public class MyUserType
{
public string ConnectionId { get; set; }
}
HomeController.cs
public class HomeController : Controller
{
public async Task<ActionResult> SaveData()
{
foreach (var mydata in DataList)
{
// save data code and show below message on UI
NotificationSend.SendToUser(mydata.Name + ": Data saved");
我可以在 UI 上收到通知,非常好,但问题是
If user A using his own machine and his login he should get only his notification , I know webapp url is same.
为此,我进行了以下更改,但此更改后没有任何通知可见。
string UserID = User.Identity.Name;
hubContext.Clients.User(UserID).Notification(mydata.Name + ": Data saved");
Layout.js
$(function () {
var notification = $.connection.notificationSend;
console.log(notification);
notification.client.Notification = function (Count) {
$('#liveupdate').empty();
$('#liveupdate').show();
$('#liveupdate').append(Count);
};
$.connection.hub.start().done(function () {
var connectionId = $.connection.hub.id;
console.log("Connected Successfully");
}).fail(function (response) {
console.log("not connected" + response);
});
});
这是我在 VB.Net 中的示例代码(您可以将其转换为 C#):
Public Class SignalRHub
Inherits Hub
Private Shared hubContext As IHubContext = GlobalHost.ConnectionManager.GetHubContext(Of SignalRHub)()
Public Sub SendToAll(ByVal msg As String)
hubContext.Clients.All.addNewMessageToPage(msg)
End Sub
Public Shared Sub SendToUser(ByVal user As String, ByVal msg As String)
hubContext.Clients.Group(user).addNewMessageToPage(msg)
End Sub
Public Overrides Function OnConnected() As Task
Dim name As String = Context.User.Identity.Name
Groups.Add(Context.ConnectionId, name)
Return MyBase.OnConnected()
End Function
End Class
你必须使用组。基本上我所做的是 1 个组用于 1 个用户。由用户名定义。
然后调用函数:
Dim user As User = idb.Users.Where(Function(a) a.id = userid).FirstOrDefault
Dim msg as string = "Any notification message"
SignalRHub.SendToUser(user.UserName, msg)
最后,javascript 代码触发:
var notification = $.connection.signalRHub;
notification.client.addNewMessageToPage = function (msg) {
$("#notification").prepend(msg);
}
您要放置通知消息的 ID 通知。
添加一个静态class它的实例将被创建一次,并将像上下文实例一样将信息持久化在内存中
public static class NotificationsResourceHandler
{
private static readonly IHubContext myContext;
public static Dictionary<string, string> Groups;
static NotificationsResourceHandler()
{
myContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
Groups = new Dictionary<string, string>();
}
public static void BroadcastNotification(dynamic model, NotificationType notificationType, string userName)
{
myContext.Clients.Group(userName).PushNotification(new { Data = model, Type = notificationType.ToString() });
}
}
并在您的中心
[HubName("yourHub")]
public class MyHub : Hub
{
public override Task OnConnected()
{
var userEmail = Context.QueryString["useremail"]?.ToLower();
if (userEmail == null) throw new Exception("Unable to Connect to Signalr hub");
if (NotificationsResourceHandler.Groups.All(x => x.Value != userEmail))
{
NotificationsResourceHandler.Groups.Add(Context.ConnectionId, userEmail);
Groups.Add(Context.ConnectionId, userEmail);
}
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
NotificationsResourceHandler.Groups.Remove(Context.ConnectionId);
Clients.All.removeConnection(Context.ConnectionId);
return base.OnDisconnected(stopCalled);
}
}
通知将推送到各个组,对于您的问题,您应该按照代码中的规定为每个用户创建一个单独的组。
我有一个 MVC 应用程序。
我已经实现了 singalR 来接收实时通知,但是如何只获取用户特定的通知。
NotificationSend.cs
public class NotificationSend : Hub
{
private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationSend>();
public static ConcurrentDictionary<string, MyUserType> MyUsers = new ConcurrentDictionary<string, MyUserType>();
public override Task OnConnected()
{
MyUsers.TryAdd(Context.ConnectionId, new MyUserType() { ConnectionId = Context.ConnectionId });
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
MyUserType garbage;
MyUsers.TryRemove(Context.ConnectionId, out garbage);
return base.OnDisconnected(stopCalled);
}
public static void SendToUser(string messageText)
{
hubContext.Clients.Client(MyUsers.Keys.ToList().FirstOrDefault()).Notification(messageText);
}
public static void StopLoader(string messageText)
{
hubContext.Clients.Client(MyUsers.Keys.ToList().FirstOrDefault()).Stoploader(messageText);
}
}
public class MyUserType
{
public string ConnectionId { get; set; }
}
HomeController.cs
public class HomeController : Controller
{
public async Task<ActionResult> SaveData()
{
foreach (var mydata in DataList)
{
// save data code and show below message on UI
NotificationSend.SendToUser(mydata.Name + ": Data saved");
我可以在 UI 上收到通知,非常好,但问题是
If user A using his own machine and his login he should get only his notification , I know webapp url is same.
为此,我进行了以下更改,但此更改后没有任何通知可见。
string UserID = User.Identity.Name;
hubContext.Clients.User(UserID).Notification(mydata.Name + ": Data saved");
Layout.js
$(function () {
var notification = $.connection.notificationSend;
console.log(notification);
notification.client.Notification = function (Count) {
$('#liveupdate').empty();
$('#liveupdate').show();
$('#liveupdate').append(Count);
};
$.connection.hub.start().done(function () {
var connectionId = $.connection.hub.id;
console.log("Connected Successfully");
}).fail(function (response) {
console.log("not connected" + response);
});
});
这是我在 VB.Net 中的示例代码(您可以将其转换为 C#):
Public Class SignalRHub
Inherits Hub
Private Shared hubContext As IHubContext = GlobalHost.ConnectionManager.GetHubContext(Of SignalRHub)()
Public Sub SendToAll(ByVal msg As String)
hubContext.Clients.All.addNewMessageToPage(msg)
End Sub
Public Shared Sub SendToUser(ByVal user As String, ByVal msg As String)
hubContext.Clients.Group(user).addNewMessageToPage(msg)
End Sub
Public Overrides Function OnConnected() As Task
Dim name As String = Context.User.Identity.Name
Groups.Add(Context.ConnectionId, name)
Return MyBase.OnConnected()
End Function
End Class
你必须使用组。基本上我所做的是 1 个组用于 1 个用户。由用户名定义。
然后调用函数:
Dim user As User = idb.Users.Where(Function(a) a.id = userid).FirstOrDefault
Dim msg as string = "Any notification message"
SignalRHub.SendToUser(user.UserName, msg)
最后,javascript 代码触发:
var notification = $.connection.signalRHub;
notification.client.addNewMessageToPage = function (msg) {
$("#notification").prepend(msg);
}
您要放置通知消息的 ID 通知。
添加一个静态class它的实例将被创建一次,并将像上下文实例一样将信息持久化在内存中
public static class NotificationsResourceHandler
{
private static readonly IHubContext myContext;
public static Dictionary<string, string> Groups;
static NotificationsResourceHandler()
{
myContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
Groups = new Dictionary<string, string>();
}
public static void BroadcastNotification(dynamic model, NotificationType notificationType, string userName)
{
myContext.Clients.Group(userName).PushNotification(new { Data = model, Type = notificationType.ToString() });
}
}
并在您的中心
[HubName("yourHub")]
public class MyHub : Hub
{
public override Task OnConnected()
{
var userEmail = Context.QueryString["useremail"]?.ToLower();
if (userEmail == null) throw new Exception("Unable to Connect to Signalr hub");
if (NotificationsResourceHandler.Groups.All(x => x.Value != userEmail))
{
NotificationsResourceHandler.Groups.Add(Context.ConnectionId, userEmail);
Groups.Add(Context.ConnectionId, userEmail);
}
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
NotificationsResourceHandler.Groups.Remove(Context.ConnectionId);
Clients.All.removeConnection(Context.ConnectionId);
return base.OnDisconnected(stopCalled);
}
}
通知将推送到各个组,对于您的问题,您应该按照代码中的规定为每个用户创建一个单独的组。