我在发布这个问题时犹豫不决,因为网上有很多可用的答案但是我运气不好,没有什么可以帮助我。对于我的Web应用程序,我需要通知部分,因为我认为使用SignalR 2。
但它不起作用。以下是完整的代码部分:
= =>轮毂类
[HubName("MyHub")]
public class MyHub : Hub
{
public static void Show()
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.displayStatus();
}
}
==&gt;全局文件
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
SqlDependency.Start(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_End()
{
SqlDependency.Stop(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
}
}
==&GT;存储库
public class DAL
{
public List<DTO.Employee> GetEmployee()
{
List<DTO.Employee> l = new List<DTO.Employee>();
try
{
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
con.Open();
using (var cmd = new SqlCommand("select * from employee", con))
{
cmd.Notification = null;
SqlDependency dep = new SqlDependency(cmd);
dep.OnChange += new OnChangeEventHandler(Dep_OnChange);
using (var drd = cmd.ExecuteReader())
{
while (drd.Read())
{
l.Add(new DTO.Employee()
{
Id = Convert.ToInt64(drd["id"]),
Name = Convert.ToString(drd["name"])
});
}
}
}
}
}
catch { }
return l;
}
private void Dep_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
MyHub.Show();
}
}
}
==&GT; Owin Startup Class
[assembly: OwinStartupAttribute(typeof(SignalR2_App1.Startup))]
namespace SignalR2_App1
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
==&GT;查看
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
$(function () {
var job = $.connection.MyHub;
job.client.displayStatus = function () {
getData();
}
$.connection.hub.start();
getData();
})
function getData() {
$.ajax({
url: "/data/getdata",
contentType: "application/json charset=utf-8",
dataType: "json",
type: "Post",
success: function (result) {
$.each(result, function (e, obj) {
$("#tbldata_tbody").append("<tr><td>" + obj.Id + "</td><td>" + obj.Name + "</td></tr>")
})
},
error: function () {
alert("Error");
}
})
}
</script>
<body>
<table id="tbldata">
<thead>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
</thead>
<tbody id="tbldata_tbody"></tbody>
</table>
==&GT;动作
[HttpPost]
public JsonResult GetData()
{
DAL.DAL O = new DAL.DAL();
return Json(O.GetEmployee());
}
您可以从以下链接下载整个代码:
Code Link
答案 0 :(得分:1)
根据您的代码,我认为您不了解信号器的所有细节。以下是一些提示:
<强> 1。在您的集线器内,您不需要GlobalHost.ConnectionsManager
在集线器内部,您已拥有Clients属性
<强> 2。不要自己创建一个hub实例!
在你DAL内你不应该打电话
MyHub.Show();
而不是grap HubContext:
GlobalHost.ConnectionManager.GetHubContext<MyHub>().Clients.All.displayStatus()
;
更好的方法 - 使用强类型中心:
根据您的代码,我认为您不了解信号器的所有细节。我建议你阅读https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server
例如,在集线器上,您应该只定义客户端可以在服务器上调用的方法。为了正确定义服务器可以在客户端上调用的方法,可以使用“Strongly-Types-Hubs”。看到: https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server#stronglytypedhubs
有关Hub对象生存期的背景信息:
https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server:
您不会实例化Hub类或从您自己的方法调用其方法 服务器上的代码;所有这些都由SignalR Hubs为您完成 管道。 SignalR每次都会创建一个Hub类的新实例 它需要处理Hub操作,例如客户端连接时, 断开连接,或对服务器进行方法调用。
由于Hub类的实例是瞬态的,因此您无法使用它们 保持状态从一个方法调用到下一个。每一次 服务器接收来自客户端的方法调用,一个新的实例 Hub类处理消息。通过多重维持状态 连接和方法调用,使用一些其他方法,如a 数据库,或Hub类上的静态变量,或其他类 这不是来自Hub。如果您将数据保留在内存中,请使用 方法如Hub类上的静态变量,数据将是 应用程序域回收时丢失。
如果要根据自己运行的代码向客户端发送消息 在Hub类之外,您无法通过实例化Hub类来实现 例如,你可以通过获取SignalR的引用来实现 Hub类的上下文对象。有关更多信息,请参见如何 稍后调用客户端方法并从Hub类外部管理组 在这个主题中。