2017-09-28 9 views
1

多くのワーカープロセスを管理するハブがあります。私は、このハブに接続し、これらのワーカープロセスのいずれかから処理ログを取得できるUIを構築したいと考えています。基本的に、これは別のクライアントから文字列を取得したいクライアントになります。私はクライアントBに送信されたクライアントAからの要求を得ることができましたが、その応答で何かを返す方法はわかりません。C#SignalRクライアントから値を返す方法

私はハブに

public void GetRunLog(int runid) 
{ 
    JobRunLog log = null; 
    JobRunClient client = this.GetClientByRunID(runid); 
    if(client != null) 
    { 
     var rawlog = Clients.Client(client.ConnectionID).GetRunLog(); 
     log = JsonConvert.DeserializeObject<JobRunLog>(rawlog); 
     Clients.Client(Context.ConnectionId).GetRunLog(log); 
    } 
} 

を簡単な方法を持っている。この要求は、クライアントによって拾われますが、私はvar rawlogが実際に何かを含むように、それが値を返すようにする方法を知りません。現時点では、これは私が思い付くことができる最良の回避策です。

myHubProxy.On("GetRunLog", (uiconnectionid) => 
{ 
    string connectionid = uiconnectionid; 
    myHubProxy.Invoke("ReturnRunLog", run.ID, run.Log, connectionid).ContinueWith(task => {}); 
}); 

これは、ワーカークライアントがログを要求していたクライアントを参照して戻って別のリクエストにログを送信するようになりますが、それは実際には最初の要求にrespnonseを返すイマイチ。私はこれを実現させる方法を見ることができません。 Invokeを使用するのではなく、要求を開始したハブのメソッドにオブジェクトを直接返すだけですか?

答えて

1

生憎ハブdoesn't keeps it's state

ハブクラスのインスタンスは一時的なので、あなたは、次の1つのメソッド呼び出しからの状態を維持するためにそれらを を使用することはできません。 サーバーがクライアントからメソッド呼び出しを受信するたびに、 Hubクラスの新しいインスタンスがメッセージを処理します。複数の 接続とメソッド呼び出しを通じて状態を維持するには、 データベース、Hubクラスの静的変数、またはHubから派生しない別のクラス など、他の方法を使用します。

ロジックを別のクラスに移動して、接続IDに関連する静的な辞書にインスタンスオブジェクトを格納してください(それを忘れないでください)。コールはハブに来るWhenewerそれが適切なインスタンスにそれをrepoints、
ここ は、インスタンスが、それはいくつかの作業をやって開始された簡略化されたサンプルだから、

public class TestingLogHub : Hub 
{ 
    public static readonly Dictionary<string, TestInstance> Instances = 
         new Dictionary<string, TestInstance>(); 

    public void SetParameter(string value) 
    { 
     Instances[Context.ConnectionId].ContinueWith(value); 
    } 
    ... 
} 

public class TestInstance : IDisposable 
{ 
    public TestInstance(string basePath, IHubContext host, string connectionId) 
    {... 
    } 
    public void ContinueWith(string value) 
    { 
     if (_nextAction == null) 
     { 
      FinishExecution(); 
     } 
     else 
     { 
      try 
      { 
       _nextAction(value); 
      } 
      catch (Exception exception) 
      { 
       Error(exception.Message); 
       FinishExecution(); 
      } 
     } 
    } 


    public void RequestParameterFor(Action<string> action, string parameter, string defaultValue = null) 
    { 
     _nextAction = action; 
     _host.Clients.Client(_connectionId).requestParameter(parameter, defaultValue??GetRandomText()); 
    } 
} 

ですが、現時点ではそれがRequestParameterForを実行し、いくつかの入力を必要としますインスタンス状態に実行される次の関数をセットし、ContinueWithの次の呼び出しを待ちます。

それは、あなたのケースでは、オブジェクトを送り返すことができますし、インスタンスにそれを提供し、多分そのリクエストの終了時にインスタンスを配置、少し一般的な例であることが唯一の必須呼び出した場合

+0

この私はどこで仕事をしていたのですか?私は、クライアントからの単純な応答を得るにはサーバーがvar response = Clients.Client(conid).somefunction()を使用するだけの方法はないと仮定していますか? –

+0

はい、正しいですが、[次のメソッド呼び出しから状態を維持するために使用することはできません](https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to- the-api/hubs-api-guide-server#hubclass) – ASpirin

関連する問題