简体   繁体   English

如何使用 SignalR 集线器将消息从服​​务器发送到客户端

[英]How do I send messages from server to client using SignalR Hubs

I am just starting to explore signalR and I would like to able to send messages from the server to all clients.我刚刚开始探索 signalR,我希望能够从服务器向所有客户端发送消息。

Here is my Hub这是我的集线器

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SignalR;
using SignalR.Hubs;
using SignalR.Hosting.Common;
using SignalR.Hosting.AspNet;
using System.Threading.Tasks;

namespace MvcApplication1
{
    public class Chat : Hub
    {
        public void Send(String message)
        {
            // Call the addMessage methods on all clients
            Clients.addMessage(message);
        }
    }
}

Here is my client Page这是我的客户页面

      <script type="text/javascript">

         $(function () {

             //Proxy created on the fly
             var chat = $.connection.chat;

             // Declare a function on the chat hub so the server can invoke it
             chat.addMessage = function (message) {
                 $("#messages").append("<li>" + message + "</li>");
             };

             $("#broadcast").click(function () {
                 // call the chat method on the server
                 chat.send($("#msg").val());
             });

             $.connection.hub.start();
         });
    </script>


}



<input type="text" id="msg" />
        <input type="button" id="broadcast" value="broadcast" />

        <ul id="messages" class="round">


        </ul>

This all works perfectly, I am able to "chat" between 2 different browsers.这一切都很完美,我能够在 2 个不同的浏览器之间“聊天”。

The next thing I want to do is initiate a message from the server to all clients.我要做的下一件事是从服务器向所有客户端发起一条消息。

So I tried this.所以我尝试了这个。

 using SignalR;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System;
using System.Web.Routing;
using SignalR;
using SignalR.Hubs;

namespace MvcApplication1
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {            
            var aTimer = new System.Timers.Timer(1000);

            aTimer.Elapsed += aTimer_Elapsed;
            aTimer.Interval = 3000;
            aTimer.Enabled = true;

            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
        }

        void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            var context = GlobalHost.ConnectionManager.GetHubContext<Chat>();
            context.Clients.Send("Hello");      
        }
    }
}

This doesn't seem to work.这似乎不起作用。 The Timer works, The "aTimer_Elapsed" event handeler runs every 3 seconds but the "Send" method on the chat hub is never run.计时器工作,“aTimer_Elapsed”事件处理程序每​​ 3 秒运行一次,但聊天中心上的“发送”方法从不运行。

Any ideas?有任何想法吗?

I think it should be我认为应该是

 void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<Chat>();
        context.Clients.All.addMessage("Hello");      
    }

instead.反而。 With Send you are calling the method used by the client to call the server...使用 Send 您正在调用客户端使用的方法来调用服务器...

Yes you must set that line to:是的,您必须将该行设置为:

void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<Chat>();
        context.Clients.All.addMessage("Hello");      
    }

However this is only half way and still wont work.然而,这只是一半,仍然行不通。

In your Js you need to write:在您的 Js 中,您需要编写:

$(function () {

//Proxy created on the fly
var chat = $.connection.chat;

// Declare a function on the chat hub so the server can invoke it
chat.client.addMessage = function (message) {
    $("#messages").append("<li>" + message + "</li>");
};

$("#broadcast").click(function () {
    // call the chat method on the server
    chat.client.addMessage($("#msg").val());
});

$.connection.hub.start();
});

I added the chat.client this will add a client-side hub method that the server will call.我添加了chat.client这将添加服务器将调用的客户端集线器方法。

In case you come across this question many years after it was asked, and you happen to use .NET 5.0 (or similar), the following may be useful as you might be using a framework that no longer offers the class GlobalHost .如果您在被问到这个问题多年后遇到这个问题,并且您碰巧使用 .NET 5.0(或类似版本),以下内容可能会很有用,因为您可能正在使用不再提供类GlobalHost的框架。

.NET 5.0 (and similar) make heavy use of dependency injection (DI) and it's not a surprise it is used here as well. .NET 5.0(和类似版本)大量使用依赖注入 (DI),在这里也使用它并不奇怪。 The following sample code shows how to do this.以下示例代码显示了如何执行此操作。 It doesn't use the class GlobalHost .它不使用类GlobalHost

Given the ChatHub class as follows:鉴于ChatHub类如下:

   public class ChatHub : Hub
   {
      public async Task SendMessage(string user, string message)
      {
         await Clients.All.SendAsync("ReceiveMessage", user, message).ConfigureAwait(false);
      }
   }

in class Startup add a line as indicated in the following code snippet:在类Startup添加一行,如以下代码片段所示:

   public class Startup
   {
      // other code omitted for brevity

      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
      {
         // other code omitted for brevity

         app.UseEndpoints(endpoints =>
         {
            endpoints.MapControllers();
            endpoints.MapHub<ChatHub>("/chatHub"); // <====== add this ======
         });

         // other code omitted for brevity
      }
   }

Then in a controller where you want to send messages to SignalR message, add the ChatHub as a dependency.然后在要向 SignalR 消息发送消息的控制器中,添加 ChatHub 作为依赖项。 The following example demonstrates how to do that for constructor injection:以下示例演示了如何为构造函数注入执行此操作:

   public class WeatherForecastController : ControllerBase
   {
      private readonly IHubContext<ChatHub> _hubContext;

      public WeatherForecastController(
         IHubContext<ChatHub> hubContext, // <============ add this ==========
         ILogger<WeatherForecastController> logger)
      {
         _hubContext = hubContext;
         _logger = logger;
      }
      
      [HttpGet]
      public virtual async Task<IEnumerable<WeatherForecastModel>> Get()
      {
         var rng = new Random();
         WeatherForecastModel[] weatherForecastModels = Enumerable.Range(1, 5).Select(index => new WeatherForecastModel
         {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)],
         }).ToArray();

         // Notify connected SignalR clients with some data:
         await _hubContext.Clients.All.SendAsync("ReceiveMessage", "the weatherman", $" The temperature will be {weatherForecastModels[0].TemperatureC}").ConfigureAwait(false);

         return weatherForecastModels;
      }

      // other code omitted for brevity
   }

This example also shows how to then send messages in the Get() method by using await _hubContext.Clients.All.SendAsync( ... )此示例还展示了如何使用await _hubContext.Clients.All.SendAsync( ... )Get()方法中发送消息

For more information see Microsoft's documentation .有关详细信息,请参阅 Microsoft 的文档

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

相关问题 在 ASP.NET Core SignalR 中,如何从服务器向客户端发送消息? - In ASP.NET Core SignalR, how do I send a message from the server to a client? 使用集线器对广播消息进行信号量规模测试 - signalr scale testing for broadcast messages using hubs SignalR:如何在Signalr中自动将内容从服务器推送到客户端? - SignalR: How do i push the contents from server to client automatically in signalr? 通过 SignalR HubContext 从集线器所在项目外部的方法发送消息 - Send messages via SignalR HubContext from method in project outside where Hubs are located 如何使用单个 TcpClient 实例将多个字符串消息从客户端发送到服务器? - How can I send multiple string messages from client to server using a single instance of TcpClient? 使用SignalR从服务器向客户端发送消息 - Sending Messages from the Server to the Client with SignalR 如何将邮件从服务器发送到特定客户端 - How to send messages from server to a specific client 如何从dotnet核心中的服务器将二进制文件发送到SignalR客户端 - how to send a binary file to SignalR client from server in dotnet core SignalR .Net客户端:如何向组发送消息? - SignalR .Net client: How do I send a message to a Group? SignalR 从客户端向服务器发送消息错误 - SignalR send message from client to server error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM