我如何在Signalr中映射用户连接和用户ID,以便可以向特定用户发送消息

时间:2019-06-23 06:20:04

标签: asp.net-core-mvc asp.net-core-signalr

我想向用户发送私人消息,我创建了一个集线器,但不幸的是,我不知道如何在Signalr核心中进行操作,文档中也没有任何文章。

1 个答案:

答案 0 :(得分:0)

  

我如何在Signalr中映射用户连接和用户ID,以便我可以向特定用户发送消息

要达到上述要求,请参考以下示例。

ChatHub类:

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客户端:

<h1>PrivateChat</h1>

<div class="container">
    <div class="row">&nbsp;</div>
    <div class="row">
        <div class="col-6">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
        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>:&nbsp;&nbsp;' + $("#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>

测试结果:

enter image description here

注意:上面的示例仅用于测试目的,如果要将用户映射到生产环境上的连接,则可以将永久外部存储(例如数据库或Azure表存储)用于存储连接信息。