2017-09-22 10 views
0

Websocketharpライブラリのリクエスト/レスポンスパラダイムを実装しようとしていますが、これはHttpClientのリクエスト/レスポンス非同期動作とまったく同じです。私は以下のコードで与えられたasyncコールバックを使用してそれを達成しようとしています。 SendAsyncメソッドのOnMessageコールバックイベントを取得して、サーバーが応答を送信するまで待機させようとしました。私はSendAsyncメソッドの範囲内で応答を取得することができますが、SendAsyncスコープから出てすぐに応答の値をクリアします。Websocket.SarpAsync()とOnMessageコールバック関数を使用したWebsocketsharpライブラリのリクエスト/応答パラダイム

string clientResponse = null; 

      var response = Task.Run(() => objWSClient.SendAsync(stream, Convert.ToInt32(stream.Length), (async (completed) => 
      { 
       if (completed) 
       { 
        clientResponse = await WSMessageSendSuccess(reqObject, callback); 

        // Websocket response is flushed to the console window, but when it leaves the scope, it doesn't hold the response out of the SendAsync() scope. 
        Console.WriteLine(clientResponse); 
       } 
       else 
       { 
        WSMessageSendFail(reqObject); 
        clientResponse = "Failure to send Message"; 
       } 
      }))); 


      while (response.Status != TaskStatus.RanToCompletion) 
      { 
       Task.Delay(10000).Wait(); 
      } 
      response.Wait(); 

      // As soon as we leave scope of WebSocket.SendAsync() method, it clears the client response variable value. 
      // variable name : clientResponse;, it also works same with static property/variable. 
      return clientResponse; 
+0

あなたは、Microsoftの記事、https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/interop-with-other-asynchronousに従うことによってAPIをカプセル化することができます-patterns-and-types#task-and-the-event-based-asynchronous-pattern -eap –

答えて

0
static Class WSClient{ 


     Private Dictionary <string, Func<string, void>> DictWSReqResp = new Dictionary <string, Func<string, void>>(); 
     Private WebSocket objWSClient; 


     public static void init(Iconfiguration config){ 
      //instantiate objWSClient here, set all handlers, and connect 
      objWSClient.OnMessage += new EventHandler<MessageEventArgs>(e_ServerMessageReceived); 
     } 




     async Task<String> Request(uri, method, payload, headers){ 

      //it is important that this be an async function and the return be an await, because this way we 
      //guarantee that the taskCS remains in scope of this function. If this were to return the task itself 
      //then the tcs will be subject to GC. 

      //the three variables below will remain alive while the task is not completed 
      TaskCompletionSource<string> taskCS = new TaskCompletionSource<string>(); 
      string trackid = trackid; 
      Action<string> callback; 

      //the sendAsync callback should NOT be async 
      objWSClient.SendAsync(stream, Convert.ToInt32(stream.Length), new Action<bool>(completed) => 
      { 
       if (completed) 
       { 
        callback = (payload)=>{ //this will not run unless called by the e_ServerMessageReceived handler 
         taskCS.SetResult(payload); 
         DictWSReqResp.delete(trackid); 
        } 
        DictWSReqResp.Add(trackid, callback); 
       } 
       else 
       { 
        //create well formed errorPayload 
        taskCS.SetException(errorPayload); 
       } 
      }); 



      return await taskCS.Task; 


     } 



     private static void e_ServerMessageReceived(payload){ //server sends {t:1 /*for responses*/, i:<trackid>, p:<response payload>} 
      if(t==1)(DictWSReqResp(payload.i))(payload.p); 

     } 

    } 
+0

醜いことは残念です。これはあなたと同じ問題の解決策です。サーバーレスポンスは、payload.iがtrackidに設定されたJSONオブジェクトです。残りは自明です。 –

+0

ロジックが欠落しています。私のクラスは、RESTメッセージをWSペイロードに変換します。 –

関連する問題