带有 SignalR 的 WCF 服务 [英] WCF Service with SignalR

查看:33
本文介绍了带有 SignalR 的 WCF 服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a web application which has few charts on dashboard. The data for charts is fetched on document.ready function at client side invoking a WCF service method.

我现在想要的是在我的应用程序中使用 SignalR.我对 SignalR 真的很陌生.我如何从 SignalR Hub 调用 WCF 方法,或者您可以说的是,我希望 WCF 服务每隔一分钟将数据推送到客户端,而不是从服务器拉取数据.

What i want is now to use SignalR in my application. I am really new to SignalR. How can i call WCF methods from SignalR Hub or what you can say is that instead of pulling data from server i want the WCF service to push data to client every one minute.

signalR 和 WCF 服务之间是否有通信方式.

Is there a way of communication between signalR and WCF service.

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

Also another approach can be to force client to ask for data from WCF Service every minute.

任何帮助将不胜感激.

到目前为止我已经完成了.

I have done following as of yet.

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

Client Side Function on my Dashboard page

<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 类如下

and my Dashboard Hub class is as follows

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启动类如下

My SignalR startup class is as follows

[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 的服务器端方法.

When i click on refresh button and a debugger on RefreshClient method on hub the debugger doesn't get to the method which means i am unable to call server side method of SignalR.

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

Is there anything needs to be done in web.config?

推荐答案

我同意 AD.Net 的评论.稍微详细一点,SignalR 集线器可以直接托管在您的 Web 项目中,有点类似于使用控制器的方式.还有一个包,这样你就可以自己托管 SignalR 库,这样它就可以自己充当服务.无论哪种方式,您都需要先访问 SignalR 集线器,因为这就是它的通信方式,然后您可以从集线器内部调用 WCF 服务方法.

I agree with AD.Net's comment. To elaborate slightly more though, the SignalR hubs can be hosted directly in your web project kinda the same way controllers are used. There is also a package out there so you can host the SignalR library on its own so it can act as a service all on its own. Either way you will need to hit the SignalR hub first as that is how it communicates then you would call your WCF service methods from within the hubs.

简要说明

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

Your HUB will have methods used by both your USER Client and your WCF Client. You may use something like UserConnected() for the user to call in and setup your logging of the connection. Then the WCF service may call your HUB with an UpdateUserStats(Guid connnectionId, UserStats stats) which would in turn call the USER client directly and provide the stats passed in like so Clients.Client(connectionId).updateStats(stats) which in turn would have a method on the USERS client named updateStats() that would handle the received information.

初始页面登陆

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

What AD.Net provided is basic code that will be called when the user lands on the page. At this point you would want to log the ConnectionId related to that user so you can directly contact them back.

第一次接触到 WCF 的集线器

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

From your Hub, you could call your WCF service as you normally would inside any normal C# code to fetch your data or perform action and return it to your user.

定期更新用户的方法

SignalR 消除了客户端代码必须不断轮询服务器以获取更新的需要.它旨在允许您将数据推送到客户端,而无需他们直接要求.这就是连接持久性发挥作用的地方.

SignalR removes the need for your client code to have to continually poll the server for updates. It is meant to allow you to push data out to the client with out them asking for it directly. This is where the persistence of the connections come into play.

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

You will probably want to create a wrapper to easily send messages to the hub from your application, since you are using WCF I would assume you have your business logic behind this layer so you will want the WCF service reaching out to your Hub whenever action X happens. You can do that by utilizing the Client side C# code as in this case your client is actually the user and the WCF service. With a chat application the other user is basically doing what you want your WCF service to do, which is send a message to the other client.

使用示例

您正在经营一家在线商店.仪表板显示当天有多少订单.因此,当用户下新订单时,您可以将呼叫连接到集线器以发送消息以更新订购的产品.您可以通过将其发送到您配置的管理员组来执行此操作,仪表板上的任何管理员都会收到该消息.但是,如果这些统计信息非常特定于用户,那么您将更有可能访问数据库,找到用户已连接的 ConnectionId 并将更新消息直接发送到该 connectionid.

You are running an online store. The dashboard displays how many orders there have been for the day. So you would wire up a call to the hub to send a message out to update the products ordered when a user places a new order. You can do this by sending it to the admin group you have configured and any admins on the dashboard would get the message. Though if these stats are very user specific, you will more then likely instead reach into the database, find the ConnectionId that the user has connected with and send the update message directly to that connectionid.

WCF 客户端代码示例

以防万一你想要一些代码,这是直接从 MS 站点连接到 .net 客户端.您可以在 WCF 服务中使用它,或者在您计划连接然后向用户发送更新的代码中的任何位置使用它.

Just incase you want some code, this is directly from MS site on connecting with a .net client. You would use this in your WCF service, or wherever in your code you plan on connecting and then sending an update to your user.

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

Here is a link directly to the .Net Client section: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-net-client

我相信您已经看过此链接,但它确实包含了您开始使用所需的所有有用信息.http://www.asp.net/signalr

I am sure you have seen this link but it really holds all the good information you need to get started. http://www.asp.net/signalr

这是一个更直接的链接,可以为您介绍如何使用代码.http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server

Here is a more direct link that goes into usages with code for you. http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server

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

ADDED: Here is a blog specific to Dashboards with SignalR and their polling. http://solomon-t.blogspot.com/2012/12/signalr-and-interval-polling-for.html

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

ADDED: Here is a page on managing users signalR connections. http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections

更新代码更新

.Net 客户端库(在 NuGet 中)使您的 .net 代码可以访问集线器.由于您是客户端,因此您需要像也是客户端的用户一样连接到集线器.您的集线器将充当此服务器.因此,对于 .Net 客户端,我假设您将设置一个 Windows 服务,该服务将在内部进行轮询,或者基于事件的某些事件将调用它的 .Net 客户端代码部分,该部分将与您的集线器联系.您的集线器将获取所提供的信息,很可能是 ConnectionId 或 GroupId,并广播用户(可能在网站上,因此它将是 JS 客户端)一种更新用户客户端前端的方法.基本上是我在简要说明"下提到的.

The .Net Client library (in NuGet) gives your .net code access to the hub. Since you are a client you will need to connect to the hub just like the User who is also a client. Your hub would act as the server for this. So with the .Net Client I am assuming you would setup a windows service that would internally poll, or something event based that would call the .Net Client code portion of it which would reach out to your hub. Your hub would take the information provided, more than likely a ConnectionId or GroupId and broad cast the User (which is perhaps on a website so it would be the JS client) a method that would update the front end for the user client. Basically what I mention under "Brief Explanation".

现在,直接回复您发布的代码.那是 Javascript,我希望像您一样进行连接.在初始连接时更新图表也很好.如果这就是全部的代码信号,尽管您缺少处理刷新的客户端方法.从技术上讲,您可以不调用 Clients.Caller.RefreshChart() 而是返回该数据并使用它,这就是您的 javascript 现在正在做的事情.你返回无效但它期待你的约会.

Now, to directly respond to the code you posted. That is Javascript, I would expect a connect like you have done. Updating the chart on initial connection is fine as well. If this is all the code signalR wise though you are missing a client side method to handle the refresh. Technically, instead of calling Clients.Caller.RefreshChart() you could just return that data and use it, which is what your javascript is doing right now. You are returning void but it is expecting a your date.

现在,我实际上会说更正您的 javascript 而不是更正集线器代码.为什么?因为在您的客户端上有一个名为refreshChart()"的 JS 方法可以在您让服务器联系并更新客户端时重复使用.

Now, I would actually say correct your javascript instead of correcting the hub code. Why? Because having a method in JS on your client that is called "refreshChart()" can be reused for when you are having your server reach out and update the client.

所以我建议,在您的 JS done 语句中删除与更新仪表板相关的任何内容.如果您想向用户发送通知或其他可以但不更新网格的内容.

So I would recommend, dropping anything that is related to updating the dashboard in your JS done statement. If you want to do a notification or something to the user that is fine but dont update the grid.

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

Now create a JS client function called "refreshChart", note the lower case R, you can call it with a big R in c# but the js library will lowercase it so when you make the function have it will receive your dashboard information.

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

Now, on the server polling, or executing on some action, your WCF would call a method on the hub that would be say "UpdateDashboar(connectionId,dashInfo)" and that method would then inside of it call the "refreshChart" just like you are doing in your RefreshClient method, accept instead of doing Clients.Caller you would use Clients.Client(connectionId).refreshChart(chartInfo).

您的代码无法正常工作的直接原因是您需要将该 Void 转换为您期望返回的类型.如果其余编码正确,您将更新一次.如果您希望它不断更新,则需要实现我提到的其他逻辑.这也是我询问您如何保持连接的原因.如果您不确定我在说什么,我添加了一个链接来帮助您.

Directly the reason your code is not working is because you need to turn that Void into the type you expect to be returned. If the rest is coded right you will have it update once. You will need to implement the other logic I mentioned if you want it constantly updating. Which is again why I asked about how you are persisting your connections. I added a link to help you with that if you are not sure what I am talking about.

这篇关于带有 SignalR 的 WCF 服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆