【问题标题】:SignalR polling database for updatesSignalR 轮询数据库以获取更新
【发布时间】:2013-01-14 13:54:20
【问题描述】:

我希望使用 SignalR 向客户端提供更新,更新将来自消息表,该消息表会在整个应用程序发生事件时更新..

我的问题是应用程序将有大约 500-600 个并发用户,我不能让所有用户都连接到数据库并不断轮询表。

id 喜欢做的是有一个单一的事情{?} 轮询表,然后更新集线器而不是每个连接轮询。我正在考虑为此使用单例?所以也许当应用程序启动时,会创建一些东西,然后真正完成所有工作..

我的问题是 - 假设我有一个单例,它有一个事件,每次有更新时都会触发。如果 500 个控制器订阅此事件,性能会如何?

另外..如果有更好的方法可以做到这一点,那么请说..这是我的第一个也是唯一的想法!

任何帮助都会很棒!

编辑:数据是由遗留应用程序提供的,我无法控制数据的输入方式,因此需要进行数据库轮询。

步骤。

【问题讨论】:

  • 您的数据库技术是什么? SQL Server、MongoDB、RavenDB 等?我问的是因为那里的一些数据库技术有一种在数据更改后立即触发通知事件的方法。
  • @tugberk 我们使用 Oracle 但我宁愿不将此解决方案与数据库技术联系起来

标签: asp.net asp.net-mvc-4 signalr


【解决方案1】:

我宁愿不要轮询数据库,因为这会很浪费。我会通过只为我的数据(HTTP API 等)打开一个入口点来解决这个问题,然后通过 SignalR Hub 向所有连接的客户端广播更新。 Brad Wilson 有一个非常酷的演示文稿,展示了这种方法:

Brad Wilson - Microsoft’s Modern Web Stack, Starring ASP.NET Web API

这里是这种方法的代码示例,它使用 ASP.NET Web API 技术进行数据输入。它使用内存中的字典进行数据存储,但这里不关心数据存储技术:

// This hub has no inbound APIs, since all inbound communication is done
// via the HTTP API. It's here for clients which want to get continuous
// notification of changes to the ToDo database.
[HubName("todo")]
public class ToDoHub : Hub { }

public abstract class ApiControllerWithHub<THub> : ApiController
    where THub : IHub {

    Lazy<IHubContext> hub = new Lazy<IHubContext>(
        () => GlobalHost.ConnectionManager.GetHubContext<THub>()
    );

    protected IHubContext Hub {

        get { return hub.Value; }
    }
}

public class ToDoController : ApiControllerWithHub<ToDoHub> {

    private static List<ToDoItem> db = new List<ToDoItem> {

        new ToDoItem { ID = 0, Title = "Do a silly demo on-stage at NDC" },
        new ToDoItem { ID = 1, Title = "Wash the car" },
        new ToDoItem { ID = 2, Title = "Get a haircut", Finished = true }
    };
    private static int lastId = db.Max(tdi => tdi.ID);

    // Lines removed for brevity

    public HttpResponseMessage PostNewToDoItem(ToDoItem item) {

        lock (db) {

            // Add item to the "database"
            item.ID = Interlocked.Increment(ref lastId);
            db.Add(item);

            // Notify the connected clients
            Hub.Clients.addItem(item);

            // Return the new item, inside a 201 response
            var response = Request.CreateResponse(HttpStatusCode.Created, item);
            string link = Url.Link("apiRoute", new { controller = "todo", id = item.ID });
            response.Headers.Location = new Uri(link);
            return response;
        }
    }

    // Lines removed for brevity
}

还提供了 Brad 演示的应用程序的完整源代码:https://github.com/bradwilson/ndc2012

另一个您不喜欢的选项是让您的数据库在数据更改后立即触发通知。然后,您可以将其拾取并通过 SignalR 进行广播。这是一个例子:

Database Change Notifications in ASP.NET using SignalR and SqlDependency

【讨论】:

  • 虽然这是一个很好的解决方案,但这对我来说是可能的。我们在遗留应用程序上添加前端,表中的数据将主要来自数据库触发器和其他数据库逻辑。
  • 如果使用 Azure。哪个不会在行更改时触发事件?返回投票?
【解决方案2】:

很抱歉这个解决方案不是signalR,但也许你可以从中得到一些想法。

这里是full example for download on GitHub

【讨论】:

  • 实际上看起来很不错,您是否有机会提供一个使用我提到的东西的例子?
  • 嘿,当然...我可以创建一个示例,其中 webclients 和(假的)其他客户端都更新数据库,控制器将信息推送给客户端...这当然可以通过一些来完成高级方法,但我会保持愚蠢和简单(开始)编辑:完成后将在此处发布链接
  • 谢谢伙计,那太棒了!
  • 嘿 Steoates。我已经创建了一个项目......将添加一些 cmets,然后为您将其放在 github 上。今晚可能在那里。
  • 页面未找到!你有备用链接吗?
猜你喜欢
  • 2010-12-25
  • 2014-04-07
  • 1970-01-01
  • 2012-12-28
  • 2020-10-17
  • 2016-07-06
  • 2012-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多