私はsignalRサーバー(コンソールアプリケーション)とクライアントアプリケーション(Asp.net MVC5)を持っています
OAuthメンバーシップで特定のユーザーにメッセージを送信する方法。
実際、ハブリクエストコンテキストから送信者ユーザーを解決することはできません。
Context.User.Identity.Name
マイハブ
public class UserHub : Hub
{
#region Hub Methods
public void LoggedIn(string userName, string uniqueId, string ip)
{
Clients.All.userLoggedIn(userName, uniqueId, ip);
}
public void LoggedOut(string userName, string uniqueId, string ip)
{
var t = ClaimsPrincipal.Current.Identity.Name;
Clients.All.userLoggedOut(userName, uniqueId, ip);
}
public void SendMessage(string sendFromId, string userId, string sendFromName, string userName, string message)
{
Clients.User(userName).sendMessage(sendFromId, userId, sendFromName, userName, message);
}
#endregion
}
ハブクラス(Program.cs)を開始
class Program
{
static void Main(string[] args)
{
string url = string.Format("http://localhost:{0}", ConfigurationManager.AppSettings["SignalRServerPort"]);
using (WebApp.Start(url))
{
Console.WriteLine("Server running on {0}", url);
Console.ReadLine();
}
}
}
connectionId
には接続された各ピアのuserName
の情報しかないことがわかっているので、クラスを作成してSignalr
をconnectionId
と維持します。
クラスを作成するUserConnection
Class UserConnection{
public string UserName {set;get;}
public string ConnectionID {set;get;}
}
リストを宣言する
List<UserConnection> uList=new List<UserConnection>();
クライアント側からの接続中にクエリ文字列としてユーザー名を渡す
$.connection.hub.qs = { 'username' : 'anik' };
接続されたmthodでこのリストに接続しているユーザーをプッシュします
public override Task OnConnected()
{
var us=new UserConnection();
us.UserName = Context.QueryString['username'];
us.ConnectionID =Context.ConnectionId;
uList.Add(us);
return base.OnConnected();
}
メッセージの送信からリストからユーザー名を検索し、ユーザー接続IDを取得してから送信します
var user = uList.Where(o=>o.UserName ==userName);
if(user.Any()){
Clients.Client(user.First().ConnectionID ).sendMessage(sendFromId, userId, sendFromName, userName, message);
}
これらの答えはすべて不必要に複雑です。 「OnConnected()」をオーバーライドし、一意のContext.ConnectionIdを取得して、すぐにクライアントのJavaScriptにブロードキャストして、クライアントが保存し、ハブサーバーへの後続の呼び出しで送信できるようにします。
public class MyHub : Hub
{
public override Task OnConnected()
{
signalConnectionId(this.Context.ConnectionId);
return base.OnConnected();
}
private void signalConnectionId(string signalConnectionId)
{
Clients.Client(signalConnectionId).signalConnectionId(signalConnectionId);
}
}
Javascriptで:
$(document).ready(function () {
// Reference the auto-generated proxy for the SignalR hub.
var myHub = $.connection.myHub;
// The callback function returning the connection id from the hub
myHub.client.signalConnectionId = function (data) {
signalConnectionId = data;
}
// Start the connection.
$.connection.hub.start().done(function () {
// load event definitions here for sending to the hub
});
});
「Context.User.identity.Name」を取得できるようにするには、認証をOWINパイプラインに統合する必要があります。
詳細については、こちらをご覧くださいSO回答: https://stackoverflow.com/a/52811043/861018
ChatHubクラスでは特定のユーザーにこれを使用します
public Task SendMessageToGroup(string groupName, string message)
{
return Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId}: {message}");
}
public async Task AddToGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has joined the group {groupName}.");
}
public async Task RemoveFromGroup(string groupName)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has left the group {groupName}.");
}