private ServiceHubRemoteHostClient(Workspace workspace, HubClient hubClient, Stream stream) :
            base(workspace)
        {
            _hubClient = hubClient;

            _rpc = JsonRpc.Attach(stream, target: this);

            // handle disconnected situation
            _rpc.Disconnected += OnRpcDisconnected;
        }
        private InProcRemoteHostClient(Workspace workspace, InProcRemoteServices inprocServices, Stream stream) :
            base(workspace)
        {
            _inprocServices = inprocServices;

            _rpc = JsonRpc.Attach(stream, target: this);

            // handle disconnected situation
            _rpc.Disconnected += OnRpcDisconnected;
        }
        private InProcRemoteHostClient(Workspace workspace, InProcRemoteServices inprocServices, Stream stream) :
            base(workspace)
        {
            _inprocServices = inprocServices;

            _rpc = JsonRpc.Attach(stream, target: this);
            _rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);

            // handle disconnected situation
            _rpc.Disconnected += OnRpcDisconnected;
        }
        private ServiceHubRemoteHostClient(
            Workspace workspace, HubClient hubClient, HostGroup hostGroup, Stream stream) :
            base(workspace)
        {
            _hubClient = hubClient;
            _hostGroup = hostGroup;

            _rpc = JsonRpc.Attach(stream, target: this);
            _rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);

            // handle disconnected situation
            _rpc.Disconnected += OnRpcDisconnected;
        }
        protected ServiceHubServiceBase(Stream stream, IServiceProvider serviceProvider)
        {
            InstanceId = Interlocked.Add(ref s_instanceId, 1);

            Logger = (TraceSource)serviceProvider.GetService(typeof(TraceSource));
            Logger.TraceInformation($"{DebugInstanceString} Service instance created");

            Stream = stream;

            _cancellationTokenSource = new CancellationTokenSource();
            CancellationToken = _cancellationTokenSource.Token;

            Rpc = JsonRpc.Attach(stream, this);
            Rpc.Disconnected += OnRpcDisconnected;
        }
Example #6
0
        protected ServiceHubServiceBase(Stream stream, IServiceProvider serviceProvider)
        {
            _instanceId = Interlocked.Add(ref s_instanceId, 1);

            // in unit test, service provider will return asset storage, otherwise, use the default one
            AssetStorage = (AssetStorage)serviceProvider.GetService(typeof(AssetStorage)) ?? AssetStorage.Default;

            Logger = (TraceSource)serviceProvider.GetService(typeof(TraceSource));
            Logger.TraceInformation($"{DebugInstanceString} Service instance created");

            _cancellationTokenSource = new CancellationTokenSource();
            CancellationToken = _cancellationTokenSource.Token;

            Rpc = JsonRpc.Attach(stream, this);
            Rpc.Disconnected += OnRpcDisconnected;
        }
Example #7
0
        public static async Task InvokeAsync(
            this JsonRpc rpc, string targetName, IReadOnlyList <object> arguments,
            Action <Stream, CancellationToken> actionWithDirectStream, CancellationToken cancellationToken)
        {
            Task task = null;

            using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                using (var stream = new ServerDirectStream())
                {
                    try
                    {
                        // send request by adding direct stream name to end of arguments
                        task = rpc.InvokeWithCancellationAsync(targetName, arguments.Concat(stream.Name).ToArray(), cancellationToken);

                        // 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))
                    {
                        // 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();

                        // record reason why task got aborted. use NFW here since we don't want to
                        // crash VS on explicitly killing OOP.
                        task.Exception.ReportServiceHubNFW("JsonRpc Invoke Failed");

                        throw;
                    }
                }
        }
Example #8
0
    public async Task Attach_NullSendingStream_CanOnlyReceiveNotifications()
    {
        var streams         = Nerdbank.FullDuplexStream.CreateStreams();
        var receivingStream = streams.Item1;
        var server          = new Server();
        var rpc             = JsonRpc.Attach(sendingStream: null, receivingStream: receivingStream, target: server);
        var disconnected    = new AsyncManualResetEvent();

        rpc.Disconnected += (s, e) => disconnected.Set();

        var helperHandler = new HeaderDelimitedMessageHandler(streams.Item2, null);
        await helperHandler.WriteAsync(JsonConvert.SerializeObject(new
        {
            jsonrpc = "2.0",
            method  = nameof(Server.NotificationMethod),
            @params = new[] { "hello" },
        }), this.TimeoutToken);

        Assert.Equal("hello", await server.NotificationReceived.WithCancellation(this.TimeoutToken));

        // Any form of outbound transmission should be rejected.
        await Assert.ThrowsAsync <InvalidOperationException>(() => rpc.NotifyAsync("foo"));

        await Assert.ThrowsAsync <InvalidOperationException>(() => rpc.InvokeAsync("foo"));

        Assert.False(disconnected.IsSet);

        // Receiving a request should forcibly terminate the stream.
        await helperHandler.WriteAsync(JsonConvert.SerializeObject(new
        {
            jsonrpc = "2.0",
            id      = 1,
            method  = nameof(Server.MethodThatAccceptsAndReturnsNull),
            @params = new object[] { null },
        }), this.TimeoutToken);

        // The connection should be closed because we can't send a response.
        await disconnected.WaitAsync().WithCancellation(this.TimeoutToken);

        // The method should not have been invoked.
        Assert.False(server.NullPassed);
    }
Example #9
0
 public ILanguageServerTarget Create(
     JsonRpc jsonRpc,
     ICapabilitiesProvider capabilitiesProvider,
     ILspWorkspaceRegistrationService workspaceRegistrationService,
     ILspLogger logger)
 {
     return(new VisualStudioInProcLanguageServer(
                _requestDispatcherFactory,
                jsonRpc,
                capabilitiesProvider,
                workspaceRegistrationService,
                GlobalOptions,
                _listenerProvider,
                logger,
                _diagnosticService,
                SupportedLanguages,
                clientName: _diagnosticsClientName,
                userVisibleServerName: this.Name,
                telemetryServerTypeName: this.GetType().Name));
 }
        public async Task Invoke(HttpContext context)
        {
            if (context.WebSockets.IsWebSocketRequest)
            {
                var webSocket = await context.WebSockets.AcceptWebSocketAsync();

                IJsonRpcMessageHandler jsonRpcMessageHandler = new WebSocketMessageHandler(webSocket);

                using (var jsonRpc = new JsonRpc(jsonRpcMessageHandler, new GreeterServer()))
                {
                    jsonRpc.StartListening();

                    await jsonRpc.Completion;
                }
            }
            else
            {
                context.Response.StatusCode = StatusCodes.Status400BadRequest;
            }
        }
Example #11
0
        private InProcRemoteHostClient(
            Workspace workspace,
            InProcRemoteServices inprocServices,
            ReferenceCountedDisposable <RemotableDataJsonRpc> remotableDataRpc,
            Stream stream) :
            base(workspace)
        {
            Contract.ThrowIfNull(remotableDataRpc);

            _inprocServices   = inprocServices;
            _remotableDataRpc = remotableDataRpc;

            _rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), target: this);
            _rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);

            // handle disconnected situation
            _rpc.Disconnected += OnRpcDisconnected;

            _rpc.StartListening();
        }
Example #12
0
        protected ServiceHubServiceBase(IServiceProvider serviceProvider, Stream stream)
        {
            InstanceId = Interlocked.Add(ref s_instanceId, 1);

            // in unit test, service provider will return asset storage, otherwise, use the default one
            AssetStorage = (AssetStorage)serviceProvider.GetService(typeof(AssetStorage)) ?? AssetStorage.Default;

            Logger = (TraceSource)serviceProvider.GetService(typeof(TraceSource));
            Logger.TraceInformation($"{DebugInstanceString} Service instance created");

            _cancellationTokenSource = new CancellationTokenSource();
            CancellationToken        = _cancellationTokenSource.Token;

            // due to this issue - https://github.com/dotnet/roslyn/issues/16900#issuecomment-277378950
            // all sub type must explicitly start JsonRpc once everything is
            // setup
            Rpc = new JsonRpc(stream, stream, this);
            Rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);
            Rpc.Disconnected += OnRpcDisconnected;
        }
Example #13
0
        static async Task Main(string[] args)
        {
            var stream = new NamedPipeClientStream(".",
                                                   "StringJsonRpc",
                                                   PipeDirection.InOut,
                                                   PipeOptions.Asynchronous);

            Console.WriteLine("正在连接服务器...");
            await stream.ConnectAsync();

            Console.WriteLine("已建立连接!");

            Console.WriteLine("我是精致码农,开始向服务端问好...");
            var jsonRpc = JsonRpc.Attach(stream);
            var message = await jsonRpc.InvokeAsync <string>("SayHello", "精致码农");

            Console.WriteLine($"来自服务端的响应:{message}");

            Console.ReadKey();
        }
        public ILanguageServerTarget Create(
            JsonRpc jsonRpc,
            ICapabilitiesProvider capabilitiesProvider,
            ILspLogger logger)
        {
            var lspMiscellaneousFilesWorkspace = new LspMiscellaneousFilesWorkspace(logger);

            return(new LanguageServerTarget(
                       _dispatcherFactory,
                       jsonRpc,
                       capabilitiesProvider,
                       _lspWorkspaceRegistrationService,
                       lspMiscellaneousFilesWorkspace,
                       _globalOptions,
                       _listenerProvider,
                       logger,
                       ProtocolConstants.RoslynLspLanguages,
                       clientName: null,
                       WellKnownLspServerKinds.CSharpVisualBasicLspServer));
        }
    public TargetObjectEventsTests(ITestOutputHelper logger)
        : base(logger)
    {
        this.server = new Server();
        this.client = new Client();

        var streams = FullDuplexStream.CreateStreams();

        this.serverStream = streams.Item1;
        this.clientStream = streams.Item2;

        this.serverRpc = JsonRpc.Attach(this.serverStream, this.server);
        this.clientRpc = JsonRpc.Attach(this.clientStream, this.client);

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

        this.serverRpc.TraceSource.Listeners.Add(new XunitTraceListener(this.Logger));
        this.clientRpc.TraceSource.Listeners.Add(new XunitTraceListener(this.Logger));
    }
            private TestLspServer(
                TestWorkspace testWorkspace,
                Dictionary <string, IList <LSP.Location> > locations,
                LSP.ClientCapabilities clientCapabilities,
                LanguageServerTarget target,
                Stream clientStream)
            {
                TestWorkspace      = testWorkspace;
                ClientCapabilities = clientCapabilities;
                _locations         = locations;

                _languageServer = target;

                _clientRpc = new JsonRpc(new HeaderDelimitedMessageHandler(clientStream, clientStream, CreateJsonMessageFormatter()))
                {
                    ExceptionStrategy = ExceptionProcessing.ISerializable,
                };

                InitializeClientRpc();
            }
        public async Task <IActionResult> Socket()
        {
            if (this.HttpContext.WebSockets.IsWebSocketRequest)
            {
                var socket = await this.HttpContext.WebSockets.AcceptWebSocketAsync();

                using (var jsonRpc = new JsonRpc(new WebSocketMessageHandler(socket), new JsonRpcServer()))
                {
                    jsonRpc.CancelLocallyInvokedMethodsWhenConnectionIsClosed = true;
                    jsonRpc.StartListening();
                    await jsonRpc.Completion;
                }

                return(new EmptyResult());
            }
            else
            {
                return(new BadRequestResult());
            }
        }
Example #18
0
        private static async Task DoJsonRpcOverWebSocketsAsync(int iterations)
        {
            var socket    = new ClientWebSocket();
            var socketUrl = new UriBuilder(serviceBaseUrl + "/api/socket?useJsonRpc=true");

            socketUrl.Scheme = "ws://";
            await socket.ConnectAsync(socketUrl.Uri, CancellationToken.None);

            using (var jsonRpc = new JsonRpc(new WebSocketMessageHandler(socket)))
            {
                var server = jsonRpc.Attach <ISocketServer>();
                jsonRpc.StartListening();
                for (int i = 0; i < iterations; i++)
                {
                    await server.HiAsync("Andrew");
                }

                await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "normal", CancellationToken.None);
            }
        }
Example #19
0
    public async Task SendMessageWithEncoding(string encodingName)
    {
        var messageHandler = new HeaderDelimitedMessageHandler(this.clientStream, this.clientStream);
        var rpcClient      = new JsonRpc(messageHandler);

        messageHandler.Encoding = Encoding.GetEncoding(encodingName);
        await rpcClient.NotifyAsync("Foo").WithCancellation(this.TimeoutToken);

        rpcClient.Dispose();

        MemoryStream seekableServerStream = await this.GetSeekableServerStream();

        int    bytesRead   = 0;
        var    reader      = new StreamReader(seekableServerStream, Encoding.ASCII);
        var    headerLines = new List <string>();
        string?line;

        while ((line = await reader.ReadLineAsync().WithCancellation(this.TimeoutToken)) != string.Empty)
        {
            Assumes.NotNull(line);
            headerLines.Add(line);
            bytesRead += line.Length + 2; // + CRLF
        }

        bytesRead += 2; // final CRLF
        this.Logger.WriteLine(string.Join(Environment.NewLine, headerLines));

        // utf-8 headers may not be present because they are the default, per the protocol spec.
        if (encodingName != "utf-8")
        {
            Assert.Contains(headerLines, l => l.Contains($"charset={encodingName}"));
        }

        // Because the first StreamReader probably read farther (to fill its buffer) than the end of the headers,
        // we need to reposition the stream at the start of the content to create a new StreamReader.
        seekableServerStream.Position = bytesRead;
        reader = new StreamReader(seekableServerStream, Encoding.GetEncoding(encodingName));
        string json = await reader.ReadToEndAsync().WithCancellation(this.TimeoutToken);

        Assert.Equal('{', json[0]);
    }
Example #20
0
        public static void Main(string[] args)
        {
#if WAIT_FOR_DEBUGGER
            while (!System.Diagnostics.Debugger.IsAttached)
            {
                System.Threading.Thread.Sleep(1000);
            }
#endif
            var messageFormatter = new JsonMessageFormatter();
            // StreamJsonRpc v1.4 serializer defaults
            messageFormatter.JsonSerializer.NullValueHandling   = NullValueHandling.Ignore;
            messageFormatter.JsonSerializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
            messageFormatter.JsonSerializer.Converters.Add(new UriConverter());

            using (CoreShell.Create()) {
                var services = CoreShell.Current.ServiceManager;

                using (var cin = Console.OpenStandardInput())
                    using (var bcin = new BufferedStream(cin))
                        using (var cout = Console.OpenStandardOutput())
                            using (var server = new LanguageServer(services))
                                using (var rpc = new JsonRpc(cout, cin, server)) {
                                    rpc.SynchronizationContext = new SingleThreadSynchronizationContext();

                                    services
                                    .AddService(new UIService(rpc))
                                    .AddService(new Client(rpc))
                                    .AddService(new TelemetryService())
                                    .AddService(messageFormatter.JsonSerializer);

                                    var cts = new CancellationTokenSource();
                                    using (new RConnection(services, cts.Token)) {
                                        var token = server.Start();
                                        rpc.StartListening();
                                        // Wait for the "stop" request.
                                        token.WaitHandle.WaitOne();
                                        cts.Cancel();
                                    }
                                }
            }
        }
Example #21
0
        private InProcLanguageServer(
            AbstractInProcLanguageClient languageClient,
            RequestDispatcher requestDispatcher,
            Workspace workspace,
            IDiagnosticService?diagnosticService,
            IAsynchronousOperationListenerProvider listenerProvider,
            ILspWorkspaceRegistrationService lspWorkspaceRegistrationService,
            string serverTypeName,
            string?clientName,
            JsonRpc jsonRpc,
            LogHubLspLogger?logger)
        {
            _languageClient    = languageClient;
            _requestDispatcher = requestDispatcher;
            _workspace         = workspace;
            _logger            = logger;

            _jsonRpc = jsonRpc;
            _jsonRpc.AddLocalRpcTarget(this);
            _jsonRpc.StartListening();

            _diagnosticService = diagnosticService;
            _listener          = listenerProvider.GetListener(FeatureAttribute.LanguageServer);
            _clientName        = clientName;

            _queue = new RequestExecutionQueue(logger ?? NoOpLspLogger.Instance, lspWorkspaceRegistrationService, languageClient.Name, serverTypeName);
            _queue.RequestServerShutdown += RequestExecutionQueue_Errored;

            // Dedupe on DocumentId.  If we hear about the same document multiple times, we only need to process that id once.
            _diagnosticsWorkQueue = new AsyncBatchingWorkQueue <DocumentId>(
                TimeSpan.FromMilliseconds(250),
                ProcessDiagnosticUpdatedBatchAsync,
                EqualityComparer <DocumentId> .Default,
                _listener,
                _queue.CancellationToken);

            if (_diagnosticService != null)
            {
                _diagnosticService.DiagnosticsUpdated += DiagnosticService_DiagnosticsUpdated;
            }
        }
Example #22
0
        internal LanguageServerTarget(
            AbstractRequestDispatcherFactory requestDispatcherFactory,
            JsonRpc jsonRpc,
            ICapabilitiesProvider capabilitiesProvider,
            LspWorkspaceRegistrationService workspaceRegistrationService,
            LspMiscellaneousFilesWorkspace?lspMiscellaneousFilesWorkspace,
            IGlobalOptionService globalOptions,
            IAsynchronousOperationListenerProvider listenerProvider,
            ILspLogger logger,
            ImmutableArray <string> supportedLanguages,
            string?clientName,
            string userVisibleServerName,
            string telemetryServerTypeName)
        {
            GlobalOptions     = globalOptions;
            RequestDispatcher = requestDispatcherFactory.CreateRequestDispatcher(supportedLanguages);

            _capabilitiesProvider        = capabilitiesProvider;
            WorkspaceRegistrationService = workspaceRegistrationService;
            Logger = logger;

            JsonRpc = jsonRpc;
            JsonRpc.AddLocalRpcTarget(this);
            JsonRpc.Disconnected += JsonRpc_Disconnected;

            Listener   = listenerProvider.GetListener(FeatureAttribute.LanguageServer);
            ClientName = clientName;

            _userVisibleServerName = userVisibleServerName;
            TelemetryServerName    = telemetryServerTypeName;

            Queue = new RequestExecutionQueue(
                logger,
                workspaceRegistrationService,
                lspMiscellaneousFilesWorkspace,
                globalOptions,
                supportedLanguages,
                userVisibleServerName,
                TelemetryServerName);
            Queue.RequestServerShutdown += RequestExecutionQueue_Errored;
        }
    public async Task BurstNotifyMessages(Stream serverStream, Stream clientStream)
    {
        var notifyServer = new NotifyServer();

        using (var serverRpc = JsonRpc.Attach(serverStream, notifyServer))
            using (var clientRpc = JsonRpc.Attach(clientStream))
            {
                serverRpc.TraceSource = new TraceSource("Server", SourceLevels.Warning);
                clientRpc.TraceSource = new TraceSource("Server", SourceLevels.Warning);
                serverRpc.TraceSource.Listeners.Add(new XunitTraceListener(this.logger));
                clientRpc.TraceSource.Listeners.Add(new XunitTraceListener(this.logger));

                // warmup
                await clientRpc.InvokeAsync("NoOp");

                const int maxIterations = 10000;
                var       notifyTasks   = new List <Task>(maxIterations);
                var       timer         = Stopwatch.StartNew();
                int       i;
                for (i = 0; i < maxIterations; i++)
                {
                    notifyTasks.Add(clientRpc.NotifyAsync("NoOp"));

                    if (timer.ElapsedMilliseconds > 2000 && i > 0)
                    {
                        // It's taking too long to reach maxIterations. Break out.
                        break;
                    }
                }

                notifyServer.RequestSignalAfter(notifyTasks.Count);
                await Task.WhenAll(notifyTasks);

                await notifyServer.Signal;

                timer.Stop();
                this.logger.WriteLine($"{i} iterations completed in {timer.ElapsedMilliseconds} ms.");
                this.logger.WriteLine($"Rate: {i / timer.Elapsed.TotalSeconds} invocations per second.");
                this.logger.WriteLine($"Overhead: {(double)timer.ElapsedMilliseconds / i} ms per invocation.");
            }
    }
Example #24
0
    public async Task ServerHasNoLeakWhenRequestIsRejected()
    {
        Task <MultiplexingStream.Channel> clientRpcChannelTask = this.clientMx.OfferChannelAsync("custom", this.TimeoutToken);
        Task <MultiplexingStream.Channel> serverRpcChannelTask = this.serverMx.AcceptChannelAsync("custom", this.TimeoutToken);

        MultiplexingStream.Channel clientRpcChannel = await clientRpcChannelTask;
        MultiplexingStream.Channel serverRpcChannel = await serverRpcChannelTask;

        this.serverRpc = new JsonRpc(new HeaderDelimitedMessageHandler(serverRpcChannel, new JsonMessageFormatter {
            MultiplexingStream = this.serverMx
        }), new ServerWithOverloads());
        this.serverRpc.StartListening();

        // Send a message, advertising a channel.
        // We *deliberately* avoid using the JsonRpc on the client side and send arguments that will cause no good match on the server
        // so as to exercise and verify the path where the server sends an error back to the client, after trying to open the channel, but without invoking the server method,
        // and without the client having a chance to close the channel before we can verify that the server did.
        MultiplexingStream.Channel oobChannel = this.clientMx.CreateChannel();
        var clientHandler = new HeaderDelimitedMessageHandler(clientRpcChannel, new JsonMessageFormatter());
        await clientHandler.WriteAsync(
            new StreamJsonRpc.Protocol.JsonRpcRequest
        {
            RequestId     = new RequestId(1),
            Method        = nameof(ServerWithOverloads.OverloadedMethod),
            ArgumentsList = new object[] { false, oobChannel.Id, new object() },
        },
            this.TimeoutToken);

        await clientRpcChannel.Output.FlushAsync(this.TimeoutToken);

        // Wait for the client to receive the error message back, but don't let any of our client code handle it.
        ReadResult readResult = await clientRpcChannel.Input.ReadAsync(this.TimeoutToken);

        clientRpcChannel.Input.AdvanceTo(readResult.Buffer.Start);

        // The test intends to exercise that the server actually accepts (or perhaps rejects) the channel.
        await oobChannel.Acceptance.WithCancellation(this.TimeoutToken);

        // Assuming it has accepted it, we want to verify that the server closes the channel.
        await oobChannel.Completion.WithCancellation(this.TimeoutToken);
    }
Example #25
0
        private async Task <ImmutableArray <SymbolInformation> > GetVsSearchResultsAsync(TestWorkspace workspace, string query)
        {
            var solution = workspace.CurrentSolution;
            var client   = (InProcRemoteHostClient)await InProcRemoteHostClient.CreateAsync(workspace.Services, runCacheCleanup : false);

            var document = solution.Projects.First().Documents.First();

            await UpdatePrimaryWorkspace(client, solution.WithDocumentFilePath(document.Id, Path.Combine(TempRoot.Root, document.FilePath)));

            var workspaceSymbolParams = new WorkspaceSymbolParams
            {
                Query = query,
            };

            var symbolResultsBuilder = ArrayBuilder <SymbolInformation> .GetInstance();

            var threadingContext  = workspace.ExportProvider.GetExportedValue <IThreadingContext>();
            var awaitableProgress = new ProgressWithCompletion <SymbolInformation[]>(symbols =>
            {
                symbolResultsBuilder.AddRange(symbols);
            }, threadingContext.JoinableTaskFactory);

            workspaceSymbolParams.PartialResultToken = awaitableProgress;

            using (var jsonRpc = JsonRpc.Attach(await client.RequestServiceAsync(WellKnownServiceHubService.LanguageServer)))
            {
                var result = await jsonRpc.InvokeWithCancellationAsync <JObject>(
                    Methods.InitializeName,
                    new object[] { new InitializeParams() },
                    CancellationToken.None);

                Assert.True(result["capabilities"]["workspaceSymbolProvider"].ToObject <bool>());

                var symbolResult = await jsonRpc.InvokeWithCancellationAsync <SymbolInformation[]>(
                    Methods.WorkspaceSymbolName,
                    new object[] { workspaceSymbolParams },
                    CancellationToken.None);
            }

            return(symbolResultsBuilder.ToImmutableAndFree());
        }
        // methods required for basic functionality

        public QsLanguageServer(Stream?sender, Stream?reader)
        {
            this.waitForInit = new ManualResetEvent(false);
            this.rpc         = new JsonRpc(sender, reader, this)
            {
                SynchronizationContext = new QsSynchronizationContext()
            };
            this.rpc.StartListening();
            this.disconnectEvent   = new ManualResetEvent(false);
            this.rpc.Disconnected += (object?s, JsonRpcDisconnectedEventArgs e) => { this.disconnectEvent.Set(); };  // let's make the server exit if the stream is disconnected
            this.ReadyForExit      = false;

            this.internalErrorTimer           = new System.Timers.Timer(60000);
            this.internalErrorTimer.Elapsed  += (_, __) => { this.showInteralErrorMessage = true; };
            this.internalErrorTimer.AutoReset = false;

            void ProcessFileEvents(IEnumerable <FileEvent> e) =>
            this.OnDidChangeWatchedFiles(JToken.Parse(JsonConvert.SerializeObject(
                                                          new DidChangeWatchedFilesParams {
                Changes = e.ToArray()
            })));

            this.fileWatcher = new FileWatcher(_ =>
                                               this.LogToWindow($"FileSystemWatcher encountered and error", MessageType.Error));
            var fileEvents = Observable.FromEvent <FileWatcher.FileEventHandler, FileEvent>(
                handler => this.fileWatcher.FileEvent += handler,
                handler => this.fileWatcher.FileEvent -= handler)
                             .Where(e => !e.Uri.LocalPath.EndsWith("tmp", StringComparison.InvariantCultureIgnoreCase) && !e.Uri.LocalPath.EndsWith('~'));

            this.projectsInWorkspace = new HashSet <Uri>();
            this.fileEvents          = new CoalesceingQueue();
            this.fileEvents.Subscribe(fileEvents, observable => ProcessFileEvents(observable));
            this.editorState = new EditorState(
                new ProjectLoader(this.LogToWindow),
                diagnostics => this.PublishDiagnosticsAsync(diagnostics),
                (name, props, meas) => this.SendTelemetryAsync(name, props, meas),
                this.LogToWindow,
                this.OnInternalError,
                this.OnTemporaryProjectLoaded);
            this.waitForInit.Set();
        }
Example #27
0
    public JsonRpcWithFatalExceptionsTests(ITestOutputHelper logger)
        : base(logger)
    {
        this.server = new Server();
        var streams = Nerdbank.FullDuplexStream.CreateStreams();

        this.clientMessageHandler = new HeaderDelimitedMessageHandler(streams.Item1, streams.Item1);
        this.serverMessageHandler = new HeaderDelimitedMessageHandler(streams.Item2, streams.Item2);

        this.clientRpc = new JsonRpc(this.clientMessageHandler);
        this.serverRpc = new JsonRpcWithFatalExceptions(this.serverMessageHandler, this.server);

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

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

        this.clientRpc.StartListening();
        this.serverRpc.StartListening();
    }
        /// <summary>
        /// Initializes a new instance of the <see cref="TermWindowControl"/> class.
        /// </summary>
        public TermWindowControl(ToolWindowContext context)
        {
            this.InitializeComponent();

            this.package   = context.Package;
            this.Focusable = true;
            this.GotFocus += TermWindowControl_GotFocus;

            var target = new TerminalEvent(context.Package, this.terminalView, context.SolutionUtils);
            var rpc    = JsonRpc.Attach(context.ServiceHubStream, target);

            context.SolutionUtils.SolutionChanged += SolutionUtils_SolutionChanged;
            VSColorTheme.ThemeChanged             += VSColorTheme_ThemeChanged;

            this.terminalView.ScriptingObject = new TerminalScriptingObject(context.Package, rpc, context.SolutionUtils, null, true, null, null, null);

            string extensionDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            string rootPath           = Path.Combine(extensionDirectory, "WebView\\default.html").Replace("\\\\", "\\");

            this.terminalView.Navigate(new Uri(rootPath));
        }
Example #29
0
    public void ServerEventRespondsToOptions(bool registerOn)
    {
        var streams = FullDuplexStream.CreateStreams();
        var rpc     = new JsonRpc(streams.Item1, streams.Item1);
        var options = new JsonRpcTargetOptions {
            NotifyClientOfEvents = registerOn
        };
        var server = new Server();

        rpc.AddLocalRpcTarget(server, options);
        if (registerOn)
        {
            Assert.NotNull(server.ServerEventAccessor);
            Assert.NotNull(server.ServerEventWithCustomArgsAccessor);
        }
        else
        {
            Assert.Null(server.ServerEventAccessor);
            Assert.Null(server.ServerEventWithCustomArgsAccessor);
        }
    }
Example #30
0
        public InProcLanguageServer(Stream inputStream, Stream outputStream, LanguageServerProtocol protocol,
                                    CodeAnalysis.Workspace workspace, IDiagnosticService diagnosticService, string?clientName)
        {
            _protocol  = protocol;
            _workspace = workspace;

            var jsonMessageFormatter = new JsonMessageFormatter();

            jsonMessageFormatter.JsonSerializer.Converters.Add(new VSExtensionConverter <TextDocumentIdentifier, VSTextDocumentIdentifier>());
            jsonMessageFormatter.JsonSerializer.Converters.Add(new VSExtensionConverter <ClientCapabilities, VSClientCapabilities>());

            _jsonRpc = new JsonRpc(new HeaderDelimitedMessageHandler(outputStream, inputStream, jsonMessageFormatter));
            _jsonRpc.AddLocalRpcTarget(this);
            _jsonRpc.StartListening();

            _diagnosticService = diagnosticService;
            _clientName        = clientName;
            _diagnosticService.DiagnosticsUpdated += DiagnosticService_DiagnosticsUpdated;

            _clientCapabilities = new VSClientCapabilities();
        }
            internal RemoteService(InteractiveHost host, Process process, int processId, JsonRpc jsonRpc)
            {
                Process = process;
                JsonRpc = jsonRpc;

                _host = host;
                _joinOutputWritingThreadsOnDisposal = _host._joinOutputWritingThreadsOnDisposal;
                _processId = processId;
                _processExitHandlerStatus = ProcessExitHandlerStatus.Uninitialized;

                // TODO (tomat): consider using single-thread async readers
                _readOutputThread              = new Thread(() => ReadOutput(error: false));
                _readOutputThread.Name         = "InteractiveHost-OutputReader-" + processId;
                _readOutputThread.IsBackground = true;
                _readOutputThread.Start();

                _readErrorOutputThread              = new Thread(() => ReadOutput(error: true));
                _readErrorOutputThread.Name         = "InteractiveHost-ErrorOutputReader-" + processId;
                _readErrorOutputThread.IsBackground = true;
                _readErrorOutputThread.Start();
            }
        public ILanguageServerTarget Create(
            JsonRpc jsonRpc,
            ICapabilitiesProvider capabilitiesProvider,
            ILspLogger logger)
        {
            var lspMiscellaneousFilesWorkspace = new LspMiscellaneousFilesWorkspace(logger);

            return(new LanguageServerTarget(
                       _dispatcherFactory,
                       jsonRpc,
                       capabilitiesProvider,
                       _lspWorkspaceRegistrationService,
                       lspMiscellaneousFilesWorkspace,
                       _globalOptions,
                       _listenerProvider,
                       logger,
                       ProtocolConstants.RoslynLspLanguages,
                       clientName: null,
                       userVisibleServerName: UserVisibleName,
                       telemetryServerTypeName: this.GetType().Name));
        }
Example #33
0
        public async Task <(JsonRpc response, string error)> PostAsync(JsonRpc request, CancellationToken cancellation)
        {
            try
            {
                if (JsonRpc.TryParse(await provider.PostAsync(request, cancellation), out JsonRpc response))
                {
                    if (response.HasError)
                    {
                        return(null, response.ErrorMessage);
                    }

                    return(response, null);
                }

                return(null, "response not parsable");
            }
            catch (Exception ex)
            {
                return(null, ex.Message);
            }
        }
Example #34
0
        public VSStreamJsonRpc()
        {
            var duplex = FullDuplexStream.CreatePipePair();

            this.SJRclientRpc = new JsonRpc(new HeaderDelimitedMessageHandler(duplex.Item1, new JsonMessageFormatter()));
            this.SJRclientRpc.StartListening();
            this.SJRserverRpc = new JsonRpc(new HeaderDelimitedMessageHandler(duplex.Item2, new JsonMessageFormatter()));
            this.SJRserverRpc.AddLocalRpcTarget(new Server());
            this.SJRserverRpc.StartListening();

            var(aPipes, bPipes) = FullDuplexStream.CreatePipePair();
            var domainA = new IO.PipeIOHeaderDelimitedRpcDomain(aPipes.Input, aPipes.Output);
            var domainB = new IO.PipeIOHeaderDelimitedRpcDomain(bPipes.Input, bPipes.Output);

            _ = domainA.StartAsync();
            _ = domainB.StartAsync();
            var entry = RpcMethodEntry.FromDelegate <Action>(new Server().NoOp);

            domainA.AddMethod(nameof(Server.NoOp), entry);
            rpcMethodHandle = new RpcMethodHandle <Empty>(domainB, nameof(Server.NoOp));
        }
Example #35
0
        private InProcRemoteHostClient(
            string clientId,
            Workspace workspace,
            InProcRemoteServices inprocServices,
            ReferenceCountedDisposable <RemotableDataJsonRpc> remotableDataRpc,
            Stream stream)
            : base(workspace)
        {
            Contract.ThrowIfNull(remotableDataRpc);

            ClientId = clientId;

            _inprocServices   = inprocServices;
            _remotableDataRpc = remotableDataRpc;

            _rpc = stream.CreateStreamJsonRpc(target: this, inprocServices.Logger);

            // handle disconnected situation
            _rpc.Disconnected += OnRpcDisconnected;

            _rpc.StartListening();
        }
Example #36
0
    public async Task CallServerWithParameterObject_NoReturnValue_WithCancellationToken()
    {
        var streams   = FullDuplexStream.CreateStreams();
        var server    = new Server();
        var serverRpc = JsonRpc.Attach(streams.Item2, server);

        var client    = new JsonRpc(streams.Item1, streams.Item1);
        var clientRpc = client.Attach <IServerWithParamsObjectNoResult>(new JsonRpcProxyOptions {
            ServerRequiresNamedArguments = true
        });

        client.StartListening();

        var cts = CancellationTokenSource.CreateLinkedTokenSource(this.TimeoutToken);

        server.ResumeMethod.Reset();
        Task task = clientRpc.SumOfParameterObject(1, 2, cts.Token);

        Assert.Equal(3, await server.MethodResult.Task);
        cts.Cancel();
        await Assert.ThrowsAnyAsync <OperationCanceledException>(() => task);
    }
 public JsonRpcAssetSource(JsonRpc rpc, TraceSource logger, CancellationToken assetChannelCancellationToken)
 {
     _rpc = rpc;
     _logger = logger;
     _assetChannelCancellationToken = assetChannelCancellationToken;
 }
Example #38
0
 public JsonRpcController(JsonRpc jsonRpc)
 {
     _jsonRpc = jsonRpc;
 }