簡體   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