Igo*_*gor 91 asp.net asp.net-mvc real-time signalr
在最新版本的Asp.Net SignalR中,添加了一种使用"IUserIdProvider"接口向特定用户发送消息的新方法.
public interface IUserIdProvider
{
string GetUserId(IRequest request);
}
public class MyHub : Hub
{
public void Send(string userId, string message)
{
Clients.User(userId).send(message);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:我如何知道我向谁发送信息?这种新方法的解释非常肤浅.SignalR 2.0.0的声明草案带有这个bug并且没有编译.有没有人实现过这个功能?
更多信息:http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections#IUserIdProvider
拥抱.
Sum*_*ant 143
SignalR为每个连接提供ConnectionId.要查找哪个连接属于谁(用户),我们需要在连接和用户之间创建映射.这取决于您在应用程序中识别用户的方式.
在SignalR 2.0中,这是通过使用inbuilt来完成的IPrincipal.Identity.Name,这是在ASP.NET身份验证期间设置的登录用户标识符.
但是,您可能需要使用不同的标识符而不是使用Identity.Name来映射与用户的连接.为此,此新提供程序可与您的自定义实现一起使用,以便将用户与连接进行映射.
让我们假设我们的应用程序使用a userId来识别每个用户.现在,我们需要向特定用户发送消息.我们有userId和message,但是SignalR还必须知道我们的帐户及连接之间的映射.
要实现这一点,首先我们需要创建一个实现IUserIdProvider以下的新类:
public class CustomUserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
// your logic to fetch a user identifier goes here.
// for example:
var userId = MyCustomUserClass.FindUserId(request.User.Identity.Name);
return userId.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
第二步是告诉SignalR使用我们CustomUserIdProvider而不是默认实现.初始化集线器配置时,可以在Startup.cs中完成此操作:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var idProvider = new CustomUserIdProvider();
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => idProvider);
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以使用userId文档中提到的用户向特定用户发送消息,例如:
public class MyHub : Hub
{
public void Send(string userId, string message)
{
Clients.User(userId).send(message);
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
The*_*Man 37
这是一个开始..接受建议/改进.
服务器
public class ChatHub : Hub
{
public void SendChatMessage(string who, string message)
{
string name = Context.User.Identity.Name;
Clients.Group(name).addChatMessage(name, message);
Clients.Group("2@2.com").addChatMessage(name, message);
}
public override Task OnConnected()
{
string name = Context.User.Identity.Name;
Groups.Add(Context.ConnectionId, name);
return base.OnConnected();
}
}
Run Code Online (Sandbox Code Playgroud)
JavaScript的
(注意上面的服务器代码中的方法addChatMessage和sendChatMessage方法)
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call to broadcast messages.
chat.client.addChatMessage = function (who, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(who).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#chat').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.sendChatMessage($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
Run Code Online (Sandbox Code Playgroud)
测试

这是使用SignarR定位特定用户的方式(不使用任何提供程序):
private static ConcurrentDictionary<string, string> clients = new ConcurrentDictionary<string, string>();
public string Login(string username)
{
clients.TryAdd(Context.ConnectionId, username);
return username;
}
// The variable 'contextIdClient' is equal to Context.ConnectionId of the user,
// once logged in. You have to store that 'id' inside a dictionaty for example.
Clients.Client(contextIdClient).send("Hello!");
Run Code Online (Sandbox Code Playgroud)
对于任何尝试在 ASP.NET Core 中执行此操作的人。您可以使用声明。
public class CustomEmailProvider : IUserIdProvider
{
public virtual string GetUserId(HubConnectionContext connection)
{
return connection.User?.FindFirst(ClaimTypes.Email)?.Value;
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用任何标识符,但它必须是唯一的。例如,如果您使用名称标识符,则意味着如果有多个用户与收件人同名,则消息也会传递给他们。我选择电子邮件是因为它对每个用户来说都是独一无二的。
然后在启动类中注册该服务。
services.AddSingleton<IUserIdProvider, CustomEmailProvider>();
Run Code Online (Sandbox Code Playgroud)
下一个。在用户注册期间添加声明。
var result = await _userManager.CreateAsync(user, Model.Password);
if (result.Succeeded)
{
await _userManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, Model.Email));
}
Run Code Online (Sandbox Code Playgroud)
向特定用户发送消息。
public class ChatHub : Hub
{
public async Task SendMessage(string receiver, string message)
{
await Clients.User(receiver).SendAsync("ReceiveMessage", message);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:消息发送者不会收到消息已发送的通知。如果您希望在发件人端收到通知。将SendMessage方法改为这样。
public async Task SendMessage(string sender, string receiver, string message)
{
await Clients.Users(sender, receiver).SendAsync("ReceiveMessage", message);
}
Run Code Online (Sandbox Code Playgroud)
仅当您需要更改默认标识符时才需要执行这些步骤。否则,跳到最后一步,您可以通过将 userIds 或 connectionIds 传递到 来简单地发送消息SendMessage。了解更多
| 归档时间: |
|
| 查看次数: |
88889 次 |
| 最近记录: |