繁体   English   中英

带SignalR的WCF服务

[英]WCF Service with SignalR

我有一个Web应用程序,它在仪表板上有很少的图表。 图表的数据在客户端的document.ready函数上获取,调用WCF服务方法。

我想要的是现在在我的应用程序中使用SignalR。 我是SignalR的新手。 我如何从SignalR Hub调用WCF方法,或者你可以说是不是从服务器提取数据而是希望WCF服务每隔一分钟将数据推送到客户端。

signalR和WCF服务之间是否存在通信方式。

另一种方法可以是强制客户端每分钟从WCF服务请求数据。

任何帮助将非常感激。

我已经做了以下的事情。

我的仪表板页面上的客户端功能

<script src="Scripts/jquery.signalR-2.0.3.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="/signalr/hubs"></script>
<a id="refresh">Refresh</a>
    $(function() {
            var dashboardHubProxy = $.connection.dashboardHub;
            $.connection.hub.start().done(function() {
                // dashboardHubProxy.server.refreshClient(parameters);
                $("#refresh").click(function() {
                    dashboardHubProxy.server.refreshClient(parameters);
                });
            });
            dashboardHubProxy.client.refreshChart = function (chartData) {
                debugger;
                DrawChart(chartData, 'Hourly Call Count For Last ' + Duration + ' Days', '#chartHourly', 'StackedAreaChart');
            };
        });

我的Dashboard Hub类如下

public class DashboardHub : Hub
{
    private readonly ReportService ReportService = new ReportService();


    public void RefreshClient(string parameters)
    {
        var chartData = ReportService.GenerateHourlyCallsTrendGraphicalReport(parameters);
        Clients.All.refreshChart(chartData);
    }
}

我的SignalR启动类如下

[assembly: OwinStartup(typeof(CallsPortalWeb.Startup), "Configuration")]
namespace CallsPortalWeb
{
    public static class Startup
    {
        public static void Configuration(IAppBuilder app)
        {
            ConfigureSignalR(app);
        }
        public static void ConfigureSignalR(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

当我在集线器上点击RefreshClient方法上的刷新按钮和调试器时,调试器没有到达方法,这意味着我无法调用SignalR的服务器端方法。

在web.config中有什么需要做的吗?

我同意AD.Net的评论。 尽管如此,SignalR集线器可以直接托管在您的Web项目中,与使用控制器的方式相同。 还有一个包,所以你可以自己托管SignalR库,这样它就可以作为一个服务单独使用。 无论哪种方式,您都需要首先点击SignalR集线器,因为它是如何通信的,然后您将从集线器内调用您的WCF服务方法。

简要说明

您的HUB将拥有USER客户端和WCF客户端使用的方法。 您可以使用UserConnected()类的东西来让用户调用并设置连接的日志记录。 然后WCF服务可以使用UpdateUserStats(Guid connnectionId, UserStats stats)调用您的HUB,它将直接调用USER客户端并提供传递的统计信息,如Clients.Client(connectionId).updateStats(stats) ,这反过来将在名为updateStats()的USERS客户端上有一个方法来处理收到的信息。

初始页面着陆

AD.Net提供的是用户登陆页面时将调用的基本代码。 此时,您需要记录与该用户相关的ConnectionId,以便您可以直接联系它们。

首先联系您的集线器接触WCF

在您的Hub中,您可以像通常在任何正常的C#代码中一样调用您的WCF服务来获取数据或执行操作并将其返回给您的用户。

定期更新用户的方法

SignalR不再需要您的客户端代码不断轮询服务器以获取更新。 它旨在允许您将数据推送到客户端,而不是直接询问它。 这就是连接的持久性发挥作用的地方。

您可能希望创建一个包装器,以便从您的应用程序轻松地将消息发送到集线器,因为您正在使用WCF我会假设您拥有此层后面的业务逻辑,因此您希望WCF服务在每次操作X时都可以到达您的Hub发生。 您可以通过使用客户端C#代码来实现这一点,因为在这种情况下,您的客户端实际上是用户和WCF服务。 使用聊天应用程序,其他用户基本上正在执行您希望WCF服务执行的操作,即向其他客户端发送消息。

用法示例

您正在运行在线商店。 仪表板显示当天的订单数量。 因此,您可以将呼叫连接到集线器以发送消息以更新用户下新订单时订购的产品。 您可以通过将其发送到您配置的管理员组来执行此操作,并且仪表板上的任何管理员都可以获得该消息。 虽然如果这些统计信息非常特定于用户,您可能会更多地进入数据库,找到用户已连接的ConnectionId,并将更新消息直接发送到该connectionid。

WCF客户端代码示例

只是想要一些代码,这是直接从MS站点连接到.net客户端。 您可以在WCF服务中使用此功能,也可以在计划连接的代码中的任何位置使用此功能,然后向用户发送更新。

var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();

这是一个直接链接到.Net客户端部分的链接: http//www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-net-client

我相信你已经看过这个链接,但它确实包含了你开始所需的所有好信息。 http://www.asp.net/signalr

这是一个更直接的链接,可以为您提供代码。 http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server

ADDED:这是一个专门针对带有SignalR的仪表板及其轮询的博客。 http://solomon-t.blogspot.com/2012/12/signalr-and-interval-polling-for.html

ADDED:这是一个关于管理用户signalR连接的页面。 http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections

更新代码更新

.Net客户端库(在NuGet中)为您的.net代码提供对集线器的访问。 由于您是客户端,因此您需要连接到集线器,就像同时也是客户端的用户一样。 您的集线器将充当此服务器。 因此,对于.Net客户端,我假设您将设置一个内部轮询的Windows服务,或基于事件的事件,它将调用它的.Net客户端代码部分,它将到达您的集线器。 您的集线器将获取所提供的信息,而不仅仅是ConnectionId或GroupId,并广泛投射用户(可能在网站上,因此它将是JS客户端)一种方法,将更新用户客户端的前端。 基本上我在“简要说明”中提到的。

现在,直接回复您发布的代码。 这是Javascript,我希望像你一样做一个连接。 在初始连接上更新图表也很好。 如果这是所有代码signalR明智,虽然你缺少一个客户端方法来处理刷新。 从技术上讲,您可以只返回该数据并使用它,而不是调用Clients.Caller.RefreshChart(),这正是您的javascript正在进行的操作。 你回来了,但它期待你的约会。

现在,我实际上会说你的javascript正确而不是纠正集线器代码。 为什么? 因为在您的客户端上有一个名为“refreshChart()”的JS方法可以在服务器伸出并更新客户端时重复使用。

所以我建议,删除与JS done语句中更新仪表板相关的任何内容。 如果你想向用户做一个通知或其他什么,但没有更新网格。

现在创建一个名为“refreshChart”的JS客户端函数,注意小写R,你可以用c#中的大R来调用它,但是js库会将它小写,所以当你使用它时它会收到你的仪表板信息。

现在,在服务器轮询或执行某些操作时,您的WCF将调用集线器上的方法,该方法将说“UpdateDashboar(connectionId,dashInfo)”,然后该方法将在其内部调用“refreshChart”就像您一样正在使用您的RefreshClient方法,接受而不是Clients.Caller,您将使用Clients.Client(connectionId).refreshChart(chartInfo)。

直接导致代码无效的原因是因为您需要将该Void转换为您希望返回的类型。 如果其余部分编码正确,您将更新一次。 如果您希望不断更新,则需要实现我提到的其他逻辑。 这就是为什么我问你如何坚持你的联系。 如果您不确定我在说什么,我添加了一个链接来帮助您。

您应该使用SignalR Hub将数据推送到客户端。 您的hub可以使用WCF service (与client相同)来获取数据。

来自client

    hub.VisitingDashBoard();

VisitingDashBoard方法的hub上:

var data = wcfClient.GetDashboardData()//may be pass the user id from the context
         Clients.Caller.UpdateDashboard(data)

当然,您的client将拥有UpdateDashboard调用的处理程序

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM