简体   繁体   English

如何向单个客户端发送 SignalR 消息?

[英]How can I send SignalR message to a single client?

For the life of me, I can't figure out how to send the SignalR message only to the client that hit the "Go" button, and no one else.在我的一生中,我无法弄清楚如何仅将 SignalR 消息发送给点击“开始”按钮的客户端,而不是其他任何人。 It all works when I send it to "All", but I can't figure out how to get the connectionID on the server, and then just send the message to the initiating client.当我将它发送到“全部”时,一切正常,但我不知道如何在服务器上获取 connectionID,然后将消息发送到发起客户端。 This is what I have working so far.这是我迄今为止所做的工作。 I'd appreciate it if you could tell me how to make this work with just the calling client -如果您能告诉我如何仅使用调用客户端来完成这项工作,我将不胜感激-

This is my Default.aspx file这是我的 Default.aspx 文件

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SignalR5._Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <div><br /><br />
                <asp:Button ID="btnGo" runat="server" Text="GO!!!" OnClick="btnGo_Click" OnClientClick="this.disabled=true;" UseSubmitBehavior="false" /><br /><br />
                <asp:Label ID="lblLog" class="#log" runat="server" Text="Begin"></asp:Label> <br /> <br />
                <asp:Label ID="lblConnectionID" runat="server" Text=""></asp:Label>
            </div>
        </ContentTemplate>
    </asp:UpdatePanel>

    <script src="Scripts/jquery-3.4.1.js"></script>
    <script src="Scripts/jquery.signalR-2.4.2.js"></script>
    <script src="signalr/hubs"></script>

    <script type="text/javascript">
        $(function() {   

            var logger = $.connection.logHub;

            logger.client.logMessage = function(msg) {

                $("#MainContent_lblLog").html(msg);
            };

            $.connection.hub.start().done(function () {
                var cid = $.connection.hub.id;
                $("#MainContent_lblConnectionID").text("ConnectionID: " + cid);
                //alert("connection Id:" + cid);
            });
        });

    </script>
</asp:Content>

This is my Default.aspx.cs file这是我的 Default.aspx.cs 文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using System.Diagnostics;

namespace SignalR5
{
    public partial class _Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnGo_Click(object sender, EventArgs e)
        {
            //The timer is just to display how long each task takes.
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            
            string strMessage = "Hello ";
            LogHub.SendMessage(strMessage);
            Thread.Sleep(2000);
            strMessage += "(" + stopWatch.Elapsed.Seconds + " Seconds)<br>what's up bro? ";

            stopWatch.Restart();
            LogHub.SendMessage(strMessage);
            Thread.Sleep(2500);
            strMessage += "(" + stopWatch.Elapsed.Seconds + " Seconds)<br>Call me soon ";

            stopWatch.Restart();
            LogHub.SendMessage(strMessage);
            Thread.Sleep(3200);
            strMessage += "(" + stopWatch.Elapsed.Seconds + " Seconds)<br>See you later ";

            stopWatch.Restart();
            LogHub.SendMessage(strMessage);
            Thread.Sleep(1800);
            strMessage += "(" + stopWatch.Elapsed.Seconds + " Seconds)<br>Okay man. See you ";

            stopWatch.Restart();
            LogHub.SendMessage(strMessage);
            Thread.Sleep(2900);
            strMessage += "(" + stopWatch.Elapsed.Seconds + " Seconds)<br>We're all Done!";
            lblLog.Text = strMessage;
            
            stopWatch.Stop();
        }
    }
}

This is my Startup1.cs file这是我的 Startup1.cs 文件

using Microsoft.Owin;
using Owin;
using System;
using System.Threading.Tasks;

[assembly: OwinStartup(typeof(SignalR5.Startup1))]

namespace SignalR5
{
    public class Startup1
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

And this is my LogHub.cs file这是我的 LogHub.cs 文件

using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SignalR5
{
    public class LogHub : Hub
    {
        // This is the only one working, but I don't want to send to all clients. 
        public static void SendMessage(string strMessage)
        {
            var hub = GlobalHost.ConnectionManager.GetHubContext("LogHub");
            hub.Clients.All.logMessage(strMessage);
   
        }
    }
}

As I mentioned, I'm having a real hard time figuring out how to just send this to the "caller" client.正如我所提到的,我真的很难弄清楚如何将它发送给“调用者”客户端。 It works fine for "All".它适用于“全部”。

Each client connecting to a SignalR hub has a unique connection id.每个连接到 SignalR 集线器的客户端都有一个唯一的连接 ID。 We can retrieve this using the Context.ConnectionId property of the hub context.我们可以使用集线器上下文的 Context.ConnectionId 属性来检索它。 Using this, we can send messages just to that particular client.使用这个,我们可以只向那个特定的客户端发送消息。 Learn more about this here. 在此处了解更多相关信息。

So for sending messages to a specific client, you're gonna need their connection Id to identify which client you are going to send the message to.因此,要将消息发送到特定客户端,您将需要他们的连接 ID 来标识您要将消息发送到哪个客户端。

I have made a demo here for sending messages to a specific user.我在这里做了一个演示,用于向特定用户发送消息。 This is the hub class.这是枢纽类。 This send method will send messages to all connected clients like usual, but the extra thing I did is, register their connection id and user name at the beginning so that I can access them later.这个发送方法会像往常一样向所有连接的客户端发送消息,但我做的额外事情是,在开始时注册他们的连接 ID 和用户名,以便我以后可以访问它们。

public static class UserHandler
    {
        // just remember when you will restart the app, object will get reset
        public static HashSet<string> ConnectedIds = new HashSet<string>();
        public static HashSet<string> ConnectedUsers = new HashSet<string>();
    }

 public void Send(string name, string message)
        {
            // registering the users
            UserHandler.ConnectedIds.Add(Context.ConnectionId);
            UserHandler.ConnectedUsers.Add(name);

            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }

This SendToSingleUser method is used for sending messages to a specific user, as for the dummy purpose I am just randomly taking the first client from the list.这个SendToSingleUser方法用于向特定用户发送消息,至于虚拟目的,我只是从列表中随机选取第一个客户端。 If you already know to which user you are going to send it, then you can pass the id to the method and look for the Id in your connection list just to make sure it's a valid connection.如果您已经知道要将其发送给哪个用户,那么您可以将 id 传递给该方法并在您的连接列表中查找该 ID,以确保它是一个有效的连接。

public void SendToSingleUser(string userName, string message)
        {

            string fromUserId = Context.ConnectionId;
            //removing the currrent user ID & name
            UserHandler.ConnectedIds.Remove(fromUserId);
            UserHandler.ConnectedUsers.Remove(userName);

            //taking a random user for sending message
            string toUserId = UserHandler.ConnectedIds.First();
            string toUserName = UserHandler.ConnectedUsers.First();

            if (toUserId != null && fromUserId != null)
            {
                // send to 
                Clients.Client(toUserId).sendPrivateMessage(userName, message);

                // send to caller user
                Clients.Caller.sendPrivateMessage(userName, message);
            }

        } 

The aspx file: aspx文件:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Chat.aspx.cs" Inherits="SignalRChat.Chat" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>SignalR Chat : Chat Page</title>

    <link href="Content/bootstrap.css" rel="stylesheet" />
    <link href="Content/style.css" rel="stylesheet" />
    <link href="Content/font-awesome.css" rel="stylesheet" />

    <script src="Scripts/jQuery-1.9.1.min.js"></script>
    <script src="Scripts/jquery.signalR-2.2.2.min.js"></script>
    <script src="Scripts/date.format.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="signalr/hubs"></script>


    <script type="text/javascript">

        $(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.broadcastMessage = function (name, message) {
                // Html encode display name and message. 
                var encodedName = $('<div />').text(name).html();
                var encodedMsg = $('<div />').text(message).html();
                // Add the message to the page. 
                $('#discussion').append('<li><strong>' + encodedName
                    + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
            };

            // Create a function that the hub can call to broadcast private messages
            chat.client.sendPrivateMessage = function (name, message) {
                // Html encode display name and message. 
                var encodedName = $('<div />').text(name).html();
                var encodedMsg = $('<div />').text(message).html();
                // Add the message to the page. 
                $('#discussion').append('<li><strong>' + encodedName
                    + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
            };


            // Get the user name and store it to prepend to messages.
            $('#displayname').val(prompt('Enter your name:', ''));
            $('#CurrentUser').append($('#displayname').val());
            // Set initial focus to message input box.  
            $('#message').focus();
            // Start the connection.
            $.connection.hub.start().done(function () {

                //send to all user
                $('#sendmessage').click(function () {

                    var msg = $("#message").val();

                    if (msg.length > 0) {
                        debugger;
                        var userName = $('#displayname').val();
                        chat.server.send(userName, msg);
                        $('#message').val('').focus();
                    }
                });

                //send to a sepcific user
                $('#sendToSingleUser').click(function () {

                    var msg = $("#message").val();

                    if (msg.length > 0) {
                        debugger;
                        var userName = $('#displayname').val();
                        chat.server.sendToSingleUser(userName, msg);
                        $('#message').val('').focus();
                    }
                });
            });
        });

    </script>

</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" ></asp:ScriptManager>
        <div class="content-wrapper">
            <div class="row">
                 <div class="container">
                    <label id="CurrentUser"> </label>
                    <input type="text" id="message" />
                    <input type="button" id="sendmessage" value="Send" />
                    <input type="button" id="sendToSingleUser" value="Send Single User" />
                    <input type="hidden" id="displayname" />
                    <ul id="discussion">
                    </ul>
                </div>
            </div>
        </div>

         <script src="Scripts/bootstrap.min.js"></script>

    </form>
</body>
</html>

The full demo will be found here完整的演示可以在这里找到

Note: This demo is different than the example that you have posted, I just wanted to gave you an idea how you can achieve the communication.注意:此演示与您发布的示例不同,我只是想告诉您如何实现通信。

当调用您的“Go”按钮时,您应该调用服务器中的“Go”方法,然后您就可以将数据发送给Caller例如:

await hub.Clients.Caller.logMessage(message);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM