我刚刚开始探索signalR,我希望能够从服务器向所有客户端发送消息。
这是我的中心
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);
}
}
}
这是我的客户页面
<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>
这一切都很完美,我可以在两个不同的浏览器之间“聊天”。
我要做的下一件事是从服务器向所有客户端发送消息。
所以我试过了。
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");
}
}
}
这似乎不起作用。定时器工作,“aTimer_Elapsed”事件handeler每3秒运行一次,但聊天中心上的“发送”方法永远不会运行。
有什么想法吗?
答案 0 :(得分:31)
我认为应该是
void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
var context = GlobalHost.ConnectionManager.GetHubContext<Chat>();
context.Clients.All.addMessage("Hello");
}
代替。使用发送,您将调用客户端用于调用服务器的方法...
答案 1 :(得分:0)
是的,您必须将该行设置为:
void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
var context = GlobalHost.ConnectionManager.GetHubContext<Chat>();
context.Clients.All.addMessage("Hello");
}
然而,这只是一半,仍然无法正常工作。
在你的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();
});
我添加了chat.client
这将添加服务器将调用的客户端集线器方法。
答案 2 :(得分:0)
如果您在被问到这个问题多年后遇到这个问题,并且您碰巧使用 .NET 5.0(或类似版本),以下内容可能会很有用,因为您可能使用的框架不再提供 {{ 1}}。
.NET 5.0(和类似版本)大量使用依赖注入 (DI),在这里也使用它并不奇怪。以下示例代码显示了如何执行此操作。它不使用 GlobalHost
类。
给定 GlobalHost
类如下:
ChatHub
在类 public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message).ConfigureAwait(false);
}
}
中添加一行,如以下代码片段所示:
Startup
然后在要向 SignalR 消息发送消息的控制器中,添加 ChatHub 作为依赖项。以下示例演示了如何为构造函数注入执行此操作:
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
}
}
此示例还展示了如何使用 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
}
Get()
方法中发送消息
有关详细信息,请参阅 Microsoft 的 documentation。