2014-06-12 65 views
8

我有一個Web應用程序,它在儀表板上有幾個圖表。圖表數據在客戶端調用WCF服務方法的document.ready函數上獲取。帶SignalR的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'); 
      }; 
     }); 

和我的儀表盤轂類上

客戶端功能如下

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有什麼需要做的嗎?

+0

我唯一真正想要的是能夠使服務器將數據推送到儀表板 –

+0

不幸的是,我們不會爲您編寫代碼,您可以提供代碼,我們可以幫助澄清它並磨練您的嘗試。我在下面提供的鏈接將解釋SignalR它不是神奇的事情,你必須閱讀和了解它,我提供了資源來做到這一點。如果你沒有提供你已經嘗試過的代碼,那麼你將無法找到你正在尋找的答案,因爲我們沒有什麼可以指導你。 – Tony

+1

爲了進一步闡述我的評論,你是否知道SignalR不會自己保留連接?你打算如何存儲誰連接誰,誰是誰的組成部分,誰將獲得你想要發送到儀表板的這些更新,你是使用靜態集合還是持久存儲在數據庫中,你打算如何使用多個服務器?這個儀表板用戶是特定用戶還是將數據發送給全世界?信號後面還有更多的東西,然後只是發送消息並從服務器更新ui。 – Tony

回答

11

我同意AD.Net的評論。儘管稍微詳細一點,SignalR集線器可以直接託管在您的Web項目中,這與控制器的使用方式相同。此外還有一個軟件包,因此您可以自行託管SignalR庫,因此它可以作爲一項服務獨立運行。無論採用哪種方式,您都需要首先點擊SignalR集線器,因爲它是如何通信的,您可以從集線器內調用您的WCF服務方法。

簡要說明

集線器將通過您的用戶客戶端,你的WCF客戶端兩種使用方法。您可以使用類似UserConnected()這樣的東西來讓用戶呼叫並設置您的連接記錄。然後WCF服務可以用UpdateUserStats(Guid connnectionId, UserStats stats)調用你的HUB,它將依次直接呼叫USER客戶端並提供傳入的統計數據,如Clients.Client(connectionId).updateStats(stats),這反過來會在名爲updateStats()的USERS客戶端上具有處理接收到的信息的方法。

初始頁面登陸

AD.Net提供的是將被稱爲基本代碼時,頁面上的用戶的土地。此時,您需要記錄與該用戶相關的ConnectionId,以便您可以直接與他們聯繫。

與輪轂接觸WCF

從集線器第一次接觸,你可以調用WCF服務,你通常會任何普通的C#代碼中獲取數據或執行操作,並返回到你的用戶。更新用戶的

方法定期

SignalR不再需要爲你的客戶端代碼必須不斷地輪詢更新服務器。這意味着您可以將數據推送給客戶,而不需要直接詢問數據。這就是連接的持久性發揮作用的地方。

您可能想要創建一個包裝,以便從應用程序輕鬆地將消息發送到集線器,因爲您使用的是WCF我假設您在此圖層後面有業務邏輯,因此您需要WCF服務向您集線器,只要行動X發生。您可以通過使用客戶端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

添加:這是一個博客,專門針對帶有SignalR的儀表板和他們的投票。 http://solomon-t.blogspot.com/2012/12/signalr-and-interval-polling-for.html

添加:這是一個管理用戶信號連接的頁面。 http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections

更新您的代碼更新

.NET客戶端庫(中的NuGet)讓你的.NET代碼訪問樞紐。既然你是一個客戶,你將需要連接到集線器,就像同樣是客戶的用戶一樣。您的中心將充當此服務器。因此,對於.Net客戶端,我假設您將設置一個內部輪詢的Windows服務,或者基於事件的事件,它將調用它的.Net客戶端代碼部分,這部分內容可以觸及到您的中心。您的中心將採用提供的信息,很可能是ConnectionId或GroupId,並廣泛地投射User(可能位於網站上,因此它將是JS客戶端),這種方法會更新用戶客戶端的前端。基本上我在「簡單解釋」下提到。

現在,直接回復您發佈的代碼。這就是Javascript,我希望像你這樣做的連接。在初始連接上更新圖表也很好。如果這是所有代碼信號,儘管您錯過了處理刷新的客戶端方法。從技術上講,不是調用Clients.Caller.RefreshChart(),你可以返回數據並使用它,這就是你的JavaScript正在做的事情。您將返回無效,但它期待您的日期。

現在,我實際上會說正確的JavaScript而不是糾正中心代碼。爲什麼?因爲在您的客戶端中有一個名爲「refreshChart()」的JS中的方法,可以在您的服務器伸出並更新客戶端時重用。

因此,我會建議,放棄任何有關更新儀表板在您的JS完成聲明。如果你想對用戶做一個通知或者一些很好但不更新網格的東西。

現在創建一個名爲「refreshChart」的JS客戶端函數,注意小寫的R,你可以用c中的大R來調用它,但是js庫會將它小寫,所以當你使該函數有它的時候它會收到你的儀表板信息。

現在,在服務器輪詢或執行某個動作時,WCF將調用集線器上的一個方法,該方法將被稱爲「UpdateDashboar(connectionId,dashInfo)」,然後該方法將在其內部調用「refreshChart 「就像你在你的RefreshClient方法中做的那樣,接受而不是做Clients.Caller你可以使用Clients.Client(connectionId).refreshChart(chartInfo)。

直接由於你的代碼不工作的原因是因爲你需要將該Void變成你期望返回的類型。如果其餘部分編碼正確,您將更新一次。如果你想不斷更新,你需要實現我提到的其他邏輯。這又是爲什麼我問你如何堅持你的聯繫。如果你不確定我在說什麼,我添加了一個鏈接來幫助你。

+0

我已將代碼添加到我的問題中,以顯示我已完成的工作,但尚未 –

+0

我已再次編輯了我的代碼,並且im仍無法在集線器上調用服務器端方法。你能檢查並指導我完成嗎? –

9

您應該使用SignalR Hub將數據推送到客戶端。您的hub可以使用WCF service(與您的client相同)來獲取數據。就在VisitingDashBoard方法hub

hub.VisitingDashBoard(); 

client

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

當然你client將有一個處理程序UpdateDashboard呼叫

+0

任何代碼示例? –