我正在使用mvc,我有一个仪表板,已使用charthelper和bootstrap管理图。现在,我想在数据库更改时更新数据。为此,我正在尝试使用信号R。
之前
我使用存储库从数据库获取数据。服务文件夹也有相应的方法。
现在。
我不确定该怎么做。
但是到目前为止,我所做的是创建了一个中心类,
返回
public static void Send()
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<DashboardHub>();
context.Clients.All.updateOnDashboard();
}
并查看
<script>
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.dashboardHub;
$.connection.hub.logging = true;
chat.client.foo = function () { };
//debugger;
// Create a function that the hub can call to broadcast messages.
chat.client.updateOnDashboard = function () {
getAllDashboardUpdates()
};
$.connection.hub.start().done(function () {
getAllDashboardUpdates();
console.log('Now connected, connection ID=' + $.connection.hub.id);
})
.fail(function () { console.log('Could not connect'); });;
//$.connection.hub.stop();
});
function getAllDashboardUpdates() {
$.ajax({
url: '/Dasdhboard/Index',
contentType: 'application/html ; charset:utf-8',
type: 'GET',
dataType: 'html'
}).success(function (result) {
//$("#refTable").html(result);
}).error(function () {
});
}
控制器方式
public ActionResult Index(int? page)
{
IEnumerable<test> newlist = null;
newlist = GetAlltest();
var data = dashboardService.GetDashboardData(page, User);
if (newlist != null)
{
return View(data);
}
return View(data);
}
寻找依赖
public IEnumerable<test> GetAlltest()
{
var messages = new List<test>();
using (var connection = new SqlConnection(_connString))
{
connection.Open();
using (var command = new SqlCommand(@"SELECT [id],[testid] FROM [dbo].[test]", connection))
{
command.Notification = null;
SqlDependency.Start(_connString);
var dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
connection.Open();
var reader = command.ExecuteReader();
while (reader.Read())
{
messages.Add(item: new test { id = (int)reader["id"] });
}
}
}
return messages;
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
DashboardHub.Send();
}
}
即使这样做了,我的看法也没有刷新。我确定代码是多余的。可能有人向我展示了一种更好的方法。或者我要去哪里错了。
这只是一种方法。我也有2张图表。
参考方案
如果我正确理解了您的代码,则当前正在建立SingalR连接,并且在客户端触发AJAX调用以从服务器获取完整HTML视图的客户端上收到updateOnDashboard(),然后使用jQuery将其插入DOM。
我将对其进行更改,以便updateOnDashboard()也接收您的新值并在客户端呈现这些值,而不是再次为HTML代码调用服务器。我会更进一步,为这些值创建一个Javascript视图模型,并使用Knockout将dashbord元素数据绑定到视图模型。然后,updateOnDashboard()只需要将这些值(参数)推送到视图模型中,HTML就会通过Knockout获得更新。
我已经在this post...或V2 post中写过一些这样的博客
我在您的代码中看不到的是检测这些数据更新的安全代码。服务器上需要一些东西来检测更改并发出那些updateOnDashboard()调用。
另请注意,您的Hub方法Send()并未在任何地方使用。集线器方法仅用于客户端到服务器的调用(传入的服务器调用)。您可能没有这些,所以您不需要集线器方法-我想。
根据您的评论进行更新:
我使用SinglaR来“实时”向Web客户端广播新添加的日志项目。在服务器端,我有一个singleton,用于测试新数据并使用SignalR将其广播到Web客户端。这里的代码:
/// <summary>
/// Singleton that periodically checks the log database for new messages and broadcasts them to all
/// connected web-clients (SignalR).
/// </summary>
public class LiveMessageTicker : ILiveMessageTicker, IRegisteredObject
{
private readonly TimeSpan updateInterval = TimeSpan.FromMilliseconds(2000);
private readonly ILogEntriesRepository repository;
private Guid lastLogEntryId = Guid.Empty;
private readonly SemaphoreSlim checkSemaphore = new SemaphoreSlim(1, 2);
private Timer checkTimer;
private readonly IHubContext hub;
/// <summary>
/// Initializes a new instance of the <see cref="LiveMessageTicker"/> class.
/// </summary>
/// <param name="repository">The database repository to use.</param>
/// <exception cref="System.ArgumentNullException"></exception>
public LiveMessageTicker(ILogEntriesRepository repository)
{
if (repository == null) { throw new ArgumentNullException(nameof(repository)); }
this.repository = repository;
// Register this instance to in ASP to free it up on shutdown
HostingEnvironment.RegisterObject(this);
// Get the server-side SignalR hub
hub = GlobalHost.ConnectionManager.GetHubContext<ServerMonitoringHub>();
// Configure a Timer that calls CheckForNewMessages all 2 sec's
checkTimer = new Timer(CheckForNewMessages, null, TimeSpan.Zero, updateInterval);
}
/// <summary>
/// Stops this instance.
/// </summary>
/// <param name="immediate">if set to <c>true</c> immediatelly.</param>
/// <seealso cref="IRegisteredObject"/>
public void Stop(bool immediate)
{
checkTimer.Dispose();
checkTimer = null;
HostingEnvironment.UnregisterObject(this);
}
private void CheckForNewMessages(object state)
{
if (checkSemaphore.Wait(500))
{
try
{
// Get new log entries
var newLogEntries = repository.GetNewLogEntries(lastLogEntryId).ToList();
// If there arent any new log entries
if (!newLogEntries.Any())
{
return;
}
lastLogEntryId = newLogEntries.Last().Id;
// Convert DB entities into DTO's for specific client needs
var logEntries = newLogEntries.Select(l => new
{
id = l.Id,
correlationId = l.CorelationIdentifier,
messageId = l.MessageId,
time = l.Time.ToLocalTime(),
level = (int)l.Level,
messageText = l.Message,
additionalData = l.AdditionalData.Select(a => new { name = a.Name, value = a.Value }).ToArray(),
tags = l.Tags.Select(t => t.Name).ToArray(),
channel = l.Channel.Name,
username = l.Username,
workstation = l.WorkstationName
}).ToList();
// Broadcast all new log entries over SignalR
hub.Clients.All.addLogMessages(logEntries);
}
finally
{
checkSemaphore.Release();
}
}
}
}
这一切都是从Global.asax.cs
开始的,在那里我创建了上述类的单个实例(该实例由ASP.Net注册,以便稍后通过HostingEnvironment.RegisterObject(this)
正确停止)。
请注意,我不会将呈现的HTML代码或视图推送到客户端。我将数据推送为JSON。服务器不渲染它,但是客户端渲染。为了在客户端上呈现它,我使用了Javascript / Typescript视图模型,该模型将传入的消息收集在Knockout ObservableArray中。此可观察数组在HTML中使用Knockout foreach
绑定(请参见here)。因此,对于数据更新,我不使用Razor和ASP.Net来生成HTML。这是最初发送的视图的全部内容,该视图中包含数据绑定并引用了我的Javascript / Typescript。与上述喜欢的博客文章中记录的内容非常相似。
当用户关闭而无需付款时,我在CI框架中使用Razorpay,请创建razor支付模型,然后取消订单,我希望按状态更改为已取消的状态触发查询。所以我怎么能检测到这一点。我已经通过单击jQuery单击关闭功能但无法使用... javascript大神给出的解决方案 Razorpay提供了JS方法来检测模式关闭。您编写的任何JS代码都不会在结帐页面上运行,因为它是…
用多个通配符替换正则表达式可在PHP中工作,而不能在JavaScript中工作 - javascript我正在尝试为两个Markdown解析器实现中心对齐:在Parsedown的PHP中(成功)在Bootstrap Markdown的JavaScript中(未成功)我遵循并找到最简单的方法是使用最终的HTML输出,只需将内联样式捕捉到标签上即可。以下正则表达式可以满足我的需要,它会根据需要将style="text-align:center;"…
JavaScript将PHP中的字符串和整数传递给函数 - javascript我正在尝试将字符串和整数都传递到同一函数中,但是引号引起了问题。我发现错误出在echo $q->info部分,我必须在此代码上使用双引号。有人可以帮我写这个$q->info,但不能获得真正的价值吗?到目前为止,我的代码是<td><a href="javascript:add(<?php echo $q->i…
在提交时在表单操作中获取变量丢失 - javascript当表单由onchange事件提交时,它不会保留get变量view。任何想法为什么会发生这种情况?提交后,这是它进入的网址,index?month=February&year=2014<form action="index?view=list" class="pure-form pure-fo…
html中的python代码和javascript代码之间的执行顺序是什么 - javascript我正在使用bottle框架动态列出用于编辑任务的链接,从逻辑上说,行是具有多个(id,任务,状态)的元组的集合,下面的代码应该给出第一个链接http://localhost:8217/edit/1 第二个环节http://localhost:8217/edit/2 如此反复但是所有的链接都是http://localhost:8217/edit/5 因此我怀疑…