private async Task <Responses.IVPNResponse> SendRecvAsync(Requests.Request request, TimeSpan timeout) { // initialize waiter Responses.IVPNResponse response = null; var evt = new ManualResetEvent(false); Action <Responses.IVPNResponse> waiter = new Action <Responses.IVPNResponse>((resp) => { if (resp.Idx == request.Idx) { if (response != null) { return; } response = resp; evt.Set(); } }); try { // register waiter lock (__ResponseWaiters) { __RequestCounter += 1; if (__RequestCounter == 0) { __RequestCounter = 1; } request.Idx = __RequestCounter; __ResponseWaiters.Add(waiter); } // send request SendRequest(request); // wait for response await Task.Run(() => { if (WaitHandle.WaitTimeout == WaitHandle.WaitAny(new WaitHandle[] { evt, __CancellationToken.Token.WaitHandle }, timeout)) { throw new TimeoutException("Response timeout"); } }); } finally { // un-register waiter lock (__ResponseWaiters) { __ResponseWaiters.Remove(waiter); } } return(response); }
private void SendRequest(Requests.Request request) { Logging.Info("Sending: " + request); lock (__StreamWriter) { __StreamWriter.WriteLine(JsonConvert.SerializeObject(request)); __StreamWriter.Flush(); } }
private async Task <TResult> SendRecvRequestAsync <TResult>(Requests.Request request) where TResult : Responses.IVPNResponse { var response = await SendRecvAsync(request, TimeSpan.FromMilliseconds(SYNC_RESPONSE_TIMEOUT_MS)); if (response is Responses.IVPNErrorResponse errorResponse) { throw new IVPNClientProxyException(errorResponse.ErrorMessage); } TResult ret = null; try { ret = (TResult)response; } catch (Exception ex) { Logging.Info($"Error casting - expected:{typeof(TResult).FullName}, received:{response.GetType()}:" + ex); } return(ret); }