8

我希望使用 SignalR 向客户端提供更新,更新将来自消息表,当应用程序发生事情时更新该消息表。

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

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

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

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

任何帮助都会很棒!

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

圣。

4

2 回答 2

14

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

Brad Wilson - Microsoft 的现代 Web 堆栈,由 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 进行广播。这是一个例子:

使用 SignalR 和 SqlDependency 的 ASP.NET 中的数据库更改通知

于 2013-01-14T15:50:11.303 回答
0

抱歉,这个解决方案不是 signalR,但也许你可以从中获得灵感。

这是在 GitHub 上下载的完整示例

于 2013-01-14T21:15:26.633 回答