Beispiel #1
0
    public async Task AddLocalRpcTarget_AdditionalTargetMethodFound()
    {
        var streams = Nerdbank.FullDuplexStream.CreateStreams();
        var rpc     = new JsonRpc(streams.Item1, streams.Item2);

        rpc.AddLocalRpcTarget(new Server());
        rpc.AddLocalRpcTarget(new AdditionalServerTargetOne());
        rpc.AddLocalRpcTarget(new AdditionalServerTargetTwo());
        rpc.StartListening();

        var serverMethodResult = await rpc.InvokeAsync <string>(nameof(Server.ServerMethod), "test");

        Assert.Equal("test!", serverMethodResult);

        var plusOneResultInt = await rpc.InvokeAsync <int>(nameof(AdditionalServerTargetOne.PlusOne), 1);

        Assert.Equal(2, plusOneResultInt);

        var plusOneResultString = await rpc.InvokeAsync <string>(nameof(AdditionalServerTargetTwo.PlusOne), "one");

        Assert.Equal("one plus one!", plusOneResultString);

        var plusTwoResult = await rpc.InvokeAsync <int>(nameof(AdditionalServerTargetTwo.PlusTwo), 1);

        Assert.Equal(3, plusTwoResult);
    }
Beispiel #2
0
        public Task ShowMessage(string message, MessageType messageType)
        {
            var parameters = new ShowMessageRequestParams {
                type    = messageType,
                message = message
            };

            return(_rpc.InvokeAsync("window/showMessage", parameters));
        }
        //private JsonRpcClient(string ipAddress, int port)
        //{
        //    m_TcpClient = new TcpClient(AddressFamily.InterNetwork);
        //    m_TcpClient.Connect(IPAddress.Parse(ipAddress), port);
        //    m_JsonRpc = JsonRpc.Attach(m_TcpClient.GetStream());
        //}

        public object RpcRequest(string method, object parameter /*, int timeout = 30000*/)
        {
            object response = null;

            //m_cts.CancelAfter(timeout);
            m_JoinableTask.Run(async delegate
            {
                //response = await m_JsonRpc.InvokeWithParameterObjectAsync<object>(method, parameter, m_cts.Token);
                response = await m_JsonRpc.InvokeAsync <object>(method, parameter);
            });
            return(response);
        }
Beispiel #4
0
        public static async Task InvokeAsync(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Func <Stream, CancellationToken, Task> funcWithDirectStreamAsync, CancellationToken cancellationToken)
        {
            try
            {
                using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                    using (var stream = new ServerDirectStream())
                    {
                        // send request by adding direct stream name to end of arguments
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        await funcWithDirectStreamAsync(stream, mergedCancellation.Token).ConfigureAwait(false);

                        // wait task to finish
                        await task.ConfigureAwait(false);
                    }
            }
            catch (OperationCanceledException)
            {
                // if cancelled due to us, throw cancellation exception.
                cancellationToken.ThrowIfCancellationRequested();

                // if canclled due to invocation is failed, rethrow merged cancellation
                throw;
            }
        }
        public async Task Stop()
        {
            try {
                if (IsStarted)
                {
                    IsStarted = false;
                    RemoveEventHandlers();

                    Log("Sending '{0}' message.", Methods.ShutdownName);
                    await jsonRpc.InvokeAsync(Methods.ShutdownName);

                    Log("Sending '{0}' message.", Methods.ExitName);
                    bool success = await jsonRpc.InvokeAsyncWithTimeout(Methods.ExitName, 1000);

                    if (!success)
                    {
                        Log("Timed out sending '{0}' message.", Methods.ExitName);
                    }
                }
            } catch (Exception ex) {
                Log("Stop error: {0}", ex);
            } finally {
                Dispose();
            }
        }
Beispiel #6
0
        public static async Task InvokeAsync(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Action <Stream, CancellationToken> actionWithDirectStream, CancellationToken cancellationToken)
        {
            using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                using (var stream = new ServerDirectStream())
                {
                    try
                    {
                        // send request by adding direct stream name to end of arguments
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        actionWithDirectStream(stream, mergedCancellation.Token);

                        // wait task to finish
                        await task.ConfigureAwait(false);
                    }
                    catch (Exception ex) when(ReportUnlessCanceled(ex, mergedCancellation.Token))
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        throw;
                    }
                }
        }
Beispiel #7
0
    public async Task BasicJsonRpc()
    {
        var(clientStream, serverStream) = FullDuplexStream.CreatePair();
        var clientFormatter = new MessagePackFormatter();
        var serverFormatter = new MessagePackFormatter();

        var clientHandler = new LengthHeaderMessageHandler(clientStream.UsePipe(), clientFormatter);
        var serverHandler = new LengthHeaderMessageHandler(serverStream.UsePipe(), serverFormatter);

        var clientRpc = new JsonRpc(clientHandler);
        var serverRpc = new JsonRpc(serverHandler, new Server());

        serverRpc.TraceSource = new TraceSource("Server", SourceLevels.Verbose);
        clientRpc.TraceSource = new TraceSource("Client", SourceLevels.Verbose);

        serverRpc.TraceSource.Listeners.Add(new XunitTraceListener(this.Logger));
        clientRpc.TraceSource.Listeners.Add(new XunitTraceListener(this.Logger));

        clientRpc.StartListening();
        serverRpc.StartListening();

        int result = await clientRpc.InvokeAsync <int>(nameof(Server.Add), 3, 5).WithCancellation(this.TimeoutToken);

        Assert.Equal(8, result);
    }
Beispiel #8
0
        public static async Task InvokeAsync(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Action <Stream, CancellationToken> actionWithDirectStream, CancellationToken cancellationToken)
        {
            using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                using (var stream = new ServerDirectStream())
                {
                    try
                    {
                        // send request by adding direct stream name to end of arguments
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        actionWithDirectStream(stream, mergedCancellation.Token);

                        // wait task to finish
                        await task.ConfigureAwait(false);
                    }
                    catch (Exception ex) when(ReportUnlessCanceled(ex, cancellationToken))
                    {
                        // important to use cancelationToken here rather than mergedCancellationToken.
                        // there is a slight delay when merged cancellation token will be notified once cancellation token
                        // is raised, it can cause one to be in cancelled mode and the other is not. here, one we
                        // actually care is the cancellation token given in, not the merged cancellation token.
                        cancellationToken.ThrowIfCancellationRequested();
                        throw;
                    }
                }
        }
Beispiel #9
0
        public static async Task <T> InvokeAsync <T>(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Func <Stream, CancellationToken, Task <T> > funcWithDirectStreamAsync, CancellationToken cancellationToken)
        {
            try
            {
                using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                    using (var stream = new ServerDirectStream())
                    {
                        // send request to asset source
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        var result = await funcWithDirectStreamAsync(stream, mergedCancellation.Token).ConfigureAwait(false);

                        // wait task to finish
                        await task.ConfigureAwait(false);

                        return(result);
                    }
            }
            catch (Exception ex) when(IsCancelled(ex))
            {
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
        public async Task <string> ReadOutputToEnd(bool isError = false)
        {
            // writes mark to the STDOUT/STDERR pipe in the remote process:
            var remoteService = await Host.TryGetServiceAsync().ConfigureAwait(false);

            if (remoteService == null)
            {
                Assert.True(false, @$ "
Remote service unavailable
STDERR: {_synchronizedErrorOutput}
STDOUT: {_synchronizedOutput}
");
            }

            var writer     = isError ? _synchronizedErrorOutput : _synchronizedOutput;
            var markPrefix = '\uFFFF';
            var mark       = markPrefix + Guid.NewGuid().ToString();

            await remoteService !.JsonRpc.InvokeAsync(nameof(InteractiveHost.Service.RemoteConsoleWriteAsync), InteractiveHost.OutputEncoding.GetBytes(mark), isError).ConfigureAwait(false);

            while (true)
            {
                var data = writer.Prefix(mark, ref _outputReadPosition[isError ? 0 : 1]);
                if (data != null)
                {
                    return(data);
                }

                await Task.Delay(10);
            }
        }
Beispiel #11
0
        public async Task InvokeAsync(string targetName, params object[] arguments)
        {
            _cancellationToken.ThrowIfCancellationRequested();

            try
            {
                await _rpc.InvokeAsync(targetName, arguments).ConfigureAwait(false);
            }
            catch (ObjectDisposedException)
            {
                // object disposed exception can be thrown from StreamJsonRpc if JsonRpc is disposed in the middle of read/write.
                // the way we added cancellation support to the JsonRpc which doesn't support cancellation natively
                // can cause this exception to happen. newer version supports cancellation token natively, but
                // we can't use it now, so we will catch object disposed exception and check cancellation token
                _cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
        internal void Log(LogLevel level, string message)
        {
            var logMessage = new LogMessageParams {
                Level   = level,
                Message = message
            };

            rpc.InvokeAsync(Methods.LogName, logMessage).Wait();
        }
Beispiel #13
0
        private void OnPublishDiagnostics(object sender, PublishDiagnosticsEventArgs e)
        {
            var parameters = new PublishDiagnosticsParams {
                uri         = e.uri,
                diagnostics = e.diagnostics.ToArray()
            };

            _rpc.InvokeAsync("textDocument/publishDiagnostics", parameters);
        }
Beispiel #14
0
        public async Task InvokeAsync(string targetName, params object[] arguments)
        {
            _cancellationToken.ThrowIfCancellationRequested();

            try
            {
                await _rpc.InvokeAsync(targetName, arguments).ConfigureAwait(false);
            }
            catch
            {
                // any exception can be thrown from StreamJsonRpc if JsonRpc is disposed in the middle of read/write.
                // until we move to newly added cancellation support in JsonRpc, we will catch exception and translate to
                // cancellation exception here. if any exception is thrown unrelated to cancellation, then we will rethrow
                // the exception
                _cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
Beispiel #15
0
 public void ExecuteCommand(string command)
 {
     try {
         EnsureHostInitialized();
         rpc.InvokeAsync(Methods.InvokeName, command).Wait();
     } catch (Exception ex) {
         string errorMessage = ExceptionUtilities.DisplayMessage(ex);
         scriptingConsole.WriteLine(errorMessage, ScriptingStyle.Error);
     }
 }
Beispiel #16
0
    public async Task AddLocalRpcTarget_NoTargetContainsRequestedMethod()
    {
        var streams = Nerdbank.FullDuplexStream.CreateStreams();
        var rpc     = new JsonRpc(streams.Item1, streams.Item2);

        rpc.AddLocalRpcTarget(new Server());
        rpc.AddLocalRpcTarget(new AdditionalServerTargetOne());
        rpc.AddLocalRpcTarget(new AdditionalServerTargetTwo());
        rpc.StartListening();

        await Assert.ThrowsAsync <RemoteMethodNotFoundException>(() => rpc.InvokeAsync("PlusThree", 1));
    }
Beispiel #17
0
        public override async void DidFinishLaunching(NSNotification notification)
        {
            this.factory = new WebSocketClientFactory();
            var uri = new Uri("ws://127.0.0.1:8080");

            this.webSocket = await this.factory.ConnectAsync(uri);

            this.jsonRpc = new JsonRpc(new WebSocketMessageHandler(webSocket));
            this.jsonRpc.StartListening();
            var result = await jsonRpc.InvokeAsync <int>("Add", 5, 10);

            Console.WriteLine(result);
        }
        private void OnGlobalOperationStarted(object sender, EventArgs e)
        {
            lock (_globalNotificationsGate)
            {
                _globalNotificationsTask = _globalNotificationsTask.ContinueWith(
                    continuation, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default).Unwrap();
            }

            async Task <GlobalNotificationState> continuation(Task <GlobalNotificationState> previousTask)
            {
                // Can only transition from NotStarted->Started.  If we hear about
                // anything else, do nothing.
                if (previousTask.Result != GlobalNotificationState.NotStarted)
                {
                    return(previousTask.Result);
                }

                await _rpc.InvokeAsync(
                    nameof(IRemoteHostService.OnGlobalOperationStarted), "").ConfigureAwait(false);

                return(GlobalNotificationState.Started);
            }
        }
Beispiel #19
0
        public bool ApplyEdit(string transaction_name, Dictionary <string, LspTypes.TextEdit[]> changes)
        {
            WorkspaceEdit edit = new WorkspaceEdit()
            {
                Changes = changes
            };
            ApplyWorkspaceEditParams parameter = new ApplyWorkspaceEditParams
            {
                Label = transaction_name,
                Edit  = edit
            };

            _ = rpc.InvokeAsync <ApplyWorkspaceEditResponse>(Methods.WorkspaceApplyEditName, parameter);
            return(true);
        }
Beispiel #20
0
        public SymbolInformation[] CMGetClassifiersSendServer(int start, int end, string ffn)
        {
            try
            {
                if (_rpc == null)
                {
                    return(null);
                }

                CMGetClassifiersParams p = new CMGetClassifiersParams();
                Uri uri = new Uri(ffn);
                p.TextDocument = uri;
                p.Start        = start;
                p.End          = end;
                SymbolInformation[] result = _rpc.InvokeAsync <SymbolInformation[]>("CMGetClassifiers", p).Result;
                return(result);
            }
            catch (Exception)
            {
            }
            return(null);
        }
Beispiel #21
0
 /// <summary>
 /// Note that StreamJSonRPC doesn't discover any methods with isSpecialName==true.
 /// This means we have to use wrapper functions for indexers.
 /// <see cref="ServerDictionary"/>
 /// </summary>
 public override string this[string key]
 {
     get
     {
         return(AsyncHelper.RunSync <string>(() => _server.InvokeAsync <string>("GetVal", key)));
     }
     set
     {
         AsyncHelper.RunSync(() => _server.InvokeAsync("SetVal", key, value));
     }
 }
Beispiel #22
0
        public async Task InitializeCodeSearchServiceAsync()
        {
            if (_jsonRpc != null)
            {
                return;
            }

            string clientPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "AzDevOpsInteractiveClient.exe");

            string pipeName = $"AzDevOpsClientPipe-{Process.GetCurrentProcess().Id}";

            _clientProcess           = new Process();
            _clientProcess.StartInfo = new ProcessStartInfo(clientPath)
            {
                Arguments =
                    $@"--RootDir ""{_repoInfo.RootDir}"" " +
                    $@"--ProjectUri {_repoInfo.ProjectUri} " +
                    $@"--ProjectName ""{_repoInfo.ProjectName}"" " +
                    $@"--RepoName ""{_repoInfo.RepoName}"" " +
                    $@"--RpcPipeName ""{pipeName}"" ",
                UseShellExecute = false,
                CreateNoWindow  = true,
            };

            _logger.LogDebug($"FastCodeNav: Launching {clientPath} with arguments '{_clientProcess.StartInfo.Arguments}'");
            if (!_clientProcess.Start())
            {
                _logger.LogError($"FastCodeNav: Failed to launch {clientPath}");
                return;
            }

            _logger.LogDebug($"FastCodeNav: Connecting to search service client with PID {_clientProcess.Id}");
            var stream = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
            await stream.ConnectAsync();

            _logger.LogDebug($"FastCodeNav: Connected to search service client.");

            var jsonRpc      = new JsonRpc(stream);
            var jsonRpcProxy = jsonRpc.Attach <ICodeSearchService>();

            jsonRpc.StartListening();
            _jsonRpc = jsonRpc;

            _logger.LogDebug($"FastCodeNav: Issuing a warmup RPC request");
            _jsonRpc.InvokeAsync("WarmUpAsync").FireAndForget(_logger);
        }
Beispiel #23
0
        public async Task GetServerStatusAsync()
        {
            if (m_TcpClient.Connected && m_JsonRpc != null)
            {
                try
                {
                    Data result = await m_JsonRpc.InvokeAsync <JsonRpcData.Data>("Server.GetStatus");

                    _ServerUpdated(result.server);
                }
                catch (StreamJsonRpc.ConnectionLostException connectionLostException)
                {
                    Debug("got connectionLostException, retrying connect...");
                    ConnectAsync(m_Ip, m_Port);
                }
            }
        }
Beispiel #24
0
        public static async Task <T> InvokeAsync <T>(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Func <Stream, CancellationToken, Task <T> > funcWithDirectStreamAsync, CancellationToken cancellationToken)
        {
            try
            {
                using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                    using (var stream = new ServerDirectStream())
                    {
                        // send request to asset source
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        var result = await funcWithDirectStreamAsync(stream, mergedCancellation.Token).ConfigureAwait(false);

                        // wait task to finish
                        await task.ConfigureAwait(false);

                        return(result);
                    }
            }
            catch (ObjectDisposedException)
            {
                // object disposed exception can be thrown from StreamJsonRpc if JsonRpc is disposed in the middle of read/write.
                // the way we added cancellation support to the JsonRpc which doesn't support cancellation natively
                // can cause this exception to happen. newer version supports cancellation token natively, but
                // we can't use it now, so we will catch object disposed exception and check cancellation token
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
            catch (OperationCanceledException)
            {
                // if cancelled due to us, throw cancellation exception.
                cancellationToken.ThrowIfCancellationRequested();

                // if canclled due to invocation is failed, rethrow merged cancellation
                throw;
            }
        }
Beispiel #25
0
            public override async Task <object> RequestAssetAsync(int serviceId, Checksum checksum, CancellationToken callerCancellationToken)
            {
                // it should succeed as long as matching VS is alive
                // TODO: add logging mechanism using Logger

                // this can be called in two ways.
                // 1. Connection to get asset is closed (the asset source we were using is disconnected - _assetChannelCancellationToken)
                //    if this asset source's channel is closed, service will move to next asset source to get the asset as long as callerCancellationToken
                //    is not cancelled
                //
                // 2. Request to required this asset has cancelled. (callerCancellationToken)
                using (var mergedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(_assetChannelCancellationToken, callerCancellationToken))
                {
                    return(await _rpc.InvokeAsync(WellKnownServiceHubServices.AssetService_RequestAssetAsync,
                                                  new object[] { serviceId, checksum.ToArray() },
                                                  (s, c) => ReadAssetAsync(s, _logger, serviceId, checksum, c), mergedCancellationToken.Token).ConfigureAwait(false));
                }
            }
        public async Task CreateConnectionAndInvokeOnce()
        {
            for (int i = 0; i < Iterations; i++)
            {
                (IDuplexPipe, IDuplexPipe)duplex = FullDuplexStream.CreatePipePair();
                using var clientRpc = new JsonRpc(CreateHandler(duplex.Item1));
                clientRpc.StartListening();

                using var serverRpc = new JsonRpc(CreateHandler(duplex.Item2));
                serverRpc.AddLocalRpcTarget(new Server());
                serverRpc.StartListening();

                await clientRpc.InvokeAsync(nameof(Server.NoOp), Array.Empty <object>());
            }

            IJsonRpcMessageHandler CreateHandler(IDuplexPipe pipe)
            {
                return(this.Formatter switch
                {
                    "JSON" => new HeaderDelimitedMessageHandler(pipe, new JsonMessageFormatter()),
                    "MessagePack" => new LengthHeaderMessageHandler(pipe, new MessagePackFormatter()),
                    _ => throw Assumes.NotReachable(),
                });
            }
Beispiel #27
0
 public async Task<string> GetHostRuntimeDirectoryAsync()
 {
     var remoteService = await Host.TryGetServiceAsync().ConfigureAwait(false);
     Assert.NotNull(remoteService);
     return await remoteService!.JsonRpc.InvokeAsync<string>(nameof(InteractiveHost.Service.GetRuntimeDirectoryAsync)).ConfigureAwait(false);
 }
Beispiel #28
0
 public void TermData(string data)
 {
     rpc.InvokeAsync("termData", data);
 }
Beispiel #29
0
 public Task SendTelemetry(object o) => _rpc.InvokeAsync("telemetry/event", o);
Beispiel #30
0
        /// <summary>
        /// Returns true if the invoke completed successfully.
        /// </summary>
        public static Task <bool> InvokeAsyncWithTimeout(this JsonRpc jsonRpc, string targetName, int timeout)
        {
            Task task = jsonRpc.InvokeAsync(targetName);

            return(WaitWithTimeout(task, timeout));
        }