问题
I want to send a private message to a user, i have created a hub but unfortunately i have no idea how to do it in signalr core, the documentation also doesn't have any article in it.
回答1:
How do i map user connection and user id in signalr so that i can send a message to a specific user
To achieve above requirement, please refer to the following example.
ChatHub class:
public class ChatHub : Hub
{
public static List<KeyValuePair<string, string>> ConnectedIds = new List<KeyValuePair<string, string>>();
public async Task SendMessage(string user, string message)
{
await Clients.Others.SendAsync("NoteUpdateNotification", user, message);
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public async Task SendPrivateMessage(string user, string message, string conid)
{
await Clients.Client(conid).SendAsync("ReceiveMessage", user, message + " (private message)");
}
public override async Task OnConnectedAsync()
{
var connId = Context.ConnectionId;
var name = Context.GetHttpContext().Request.Query["user"].ToString();
ConnectedIds.Add(new KeyValuePair<string, string>(connId, name));
await Clients.All.SendAsync("updateList", ConnectedIds);
await base.OnConnectedAsync();
}
}
SignalR JavaScript Client:
<h1>PrivateChat</h1>
<div class="container">
<div class="row"> </div>
<div class="row">
<div class="col-6"> </div>
<div class="col-6">
User..........
<span id="uname"></span>
@*<input type="text" id="userInput" />*@
<br />
Message...<input type="text" id="messageInput" />
<input type="button" id="sendButton" value="Send Message" />
</div>
</div>
<div class="row">
<div class="col-12">
<hr />
</div>
</div>
<div class="row">
<div class="col-6"> </div>
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
<div class="row">
<div class="col-12">
<hr />
</div>
</div>
<div class="row">
<div class="col-6"> </div>
<div class="col-6">
<h2>Online Users</h2>
<div>
<!--<ul id="user_list"></ul>-->
<div id="online"></div>
</div>
</div>
<div class="col-12">
<hr />
</div>
<div class="col-6"> </div>
<div class="col-6">
<h2>Private Message</h2>
<div id="user_id"></div>
<input type="text" id="txtPrivateMessage" />
<input type="button" id="sendprivatemessage" value="Send Private Message" />
<input type="hidden" id="pconnId" value="" />
<ul id="privatemessagelogs"></ul>
</div>
</div>
</div>
<script>
var user = prompt('Enter your name:', '');
$("#uname").text(user);
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub?user=" + user).build();
//Disable send button until connection is established
$("#sendButton").disabled = true;
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var encodedMsg = user + " says " + msg;
var li = "<li>" + encodedMsg + "</li>";
$("#messagesList").append(li);
});
connection.on("updateList", function (ids) {
$('#online').empty();
console.log(ids);
$.each(ids, function (k, v) {
console.log(v["key"] + "/" + v["value"]);
if (v["value"].toString() != user) {
$('#online').append("<span onclick=getValue('" + v["key"] + "','" + v["value"] + "')>" + v["value"] + "</span><br/>");
}
});
});
connection.start().then(function () {
$("#sendButton").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});
$("#sendButton").on("click", function (event) {
var message = $("#messageInput").val();
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
$("#sendprivatemessage").on("click", function (event) {
var message = $("#txtPrivateMessage").val();
var conid = $("#pconnId").val();
connection.invoke("SendPrivateMessage", user, message, conid).catch(function (err) {
return console.error(err.toString());
});
$('#privatemessagelogs').append('<li><strong>You sent: </strong>: ' + $("#txtPrivateMessage").val() + '</li>');
event.preventDefault();
});
function getValue(userId, name) {
$("#user_id").text("Name: " + name + "Connection Id: " + userId);
$("#pconnId").val(userId);
$("#txtPrivateMessage").val("");
$('#privatemessagelogs').empty();
}
</script>
Test Result:
Note: The above example just for testing purpose, if you'd like to mapping user to connections on production environment, you can use permanent external storage, such as a database or Azure table storage for storing connection information.
来源:https://stackoverflow.com/questions/56721522/how-do-i-map-user-connection-and-user-id-in-signalr-so-that-i-can-send-a-message