Пример #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);
    }
Пример #2
0
        void EnsureHostInitialized()
        {
            if (messageHandler != null)
            {
                return;
            }

            if (!ShouldRestartProcess())
            {
                throw new ApplicationException(GettextCatalog.GetString("Unable to restart PowerShell host"));
            }

            process         = StartPowerShellHost();
            process.Exited += Process_Exited;

            messageHandler = new PowerShellHostMessageHandler(scriptingConsole);

            rpc = new JsonRpc(process.StandardInput.BaseStream, process.StandardOutput.BaseStream, messageHandler);
            rpc.Disconnected += JsonRpcDisconnected;

            itemOperationsMessageHandler = new ItemOperationsMessageHandler();
            rpc.AddLocalRpcTarget(itemOperationsMessageHandler);

            solutionMessageHandler = new SolutionMessageHandler();
            rpc.AddLocalRpcTarget(solutionMessageHandler);

            projectMessageHandler = new ProjectMessageHandler();
            rpc.AddLocalRpcTarget(projectMessageHandler);

            rpc.StartListening();
            rpc.JsonSerializer.NullValueHandling = NullValueHandling.Ignore;
        }
Пример #3
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));
    }
Пример #4
0
        public RemoteEndPoint(Stream stream, TraceSource logger, object?incomingCallTarget, IEnumerable <JsonConverter>?jsonConverters = null)
        {
            RoslynDebug.Assert(stream != null);
            RoslynDebug.Assert(logger != null);

            _logger = logger;

            var jsonFormatter = new JsonMessageFormatter();

            if (jsonConverters != null)
            {
                jsonFormatter.JsonSerializer.Converters.AddRange(jsonConverters);
            }

            jsonFormatter.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);

            _rpc = new JsonRpc(new HeaderDelimitedMessageHandler(stream, jsonFormatter))
            {
                CancelLocallyInvokedMethodsWhenConnectionIsClosed = true,
                TraceSource = logger
            };

            if (incomingCallTarget != null)
            {
                _rpc.AddLocalRpcTarget(incomingCallTarget, s_jsonRpcTargetOptions);
            }

            _rpc.Disconnected += OnDisconnected;
        }
Пример #5
0
        public InProcLanguageServer(
            AbstractInProcLanguageClient languageClient,
            Stream inputStream,
            Stream outputStream,
            AbstractRequestHandlerProvider requestHandlerProvider,
            Workspace workspace,
            IAsynchronousOperationListenerProvider listenerProvider,
            ILspSolutionProvider solutionProvider,
            string?clientName)
        {
            _languageClient         = languageClient;
            _requestHandlerProvider = requestHandlerProvider;
            _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();

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

            _queue = new RequestExecutionQueue(solutionProvider);
            _queue.RequestServerShutdown += RequestExecutionQueue_Errored;
        }
Пример #6
0
        public RemoteEndPoint(Stream stream, TraceSource logger, object?incomingCallTarget, IEnumerable <JsonConverter>?jsonConverters = null)
        {
            RoslynDebug.Assert(stream != null);
            RoslynDebug.Assert(logger != null);

            _id     = Interlocked.Increment(ref s_id);
            _logger = logger;

            var jsonFormatter = new JsonMessageFormatter();

            // disable interpreting of strings as DateTime during deserialization:
            jsonFormatter.JsonSerializer.DateParseHandling = DateParseHandling.None;

            if (jsonConverters != null)
            {
                jsonFormatter.JsonSerializer.Converters.AddRange(jsonConverters);
            }

            jsonFormatter.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);

            _rpc = new JsonRpc(new HeaderDelimitedMessageHandler(stream, jsonFormatter))
            {
                CancelLocallyInvokedMethodsWhenConnectionIsClosed = true,
                TraceSource = logger
            };

            if (incomingCallTarget != null)
            {
                _rpc.AddLocalRpcTarget(incomingCallTarget, s_jsonRpcTargetOptions);
            }

            _rpc.Disconnected += OnDisconnected;
        }
        private async Task StartAsync()
        {
            while (!_cancellation.Token.IsCancellationRequested)
            {
                using (var pipe = new NamedPipeServerStream(_pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
                {
                    try
                    {
                        await pipe.WaitForConnectionAsync(_cancellation.Token);

                        using (var rpc = new JsonRpc(pipe))
                        {
                            var target = _create();
                            rpc.AddLocalRpcTarget <TInterface>(target, null);
                            rpc.StartListening();
                            await rpc.Completion;
                        }
                    }
                    catch (Exception e)
                    {
                        if (!_cancellation.Token.IsCancellationRequested)
                        {
                            _logger.LogError(e, "");
                        }
                    }
                }
            }
        }
Пример #8
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();
        }
Пример #9
0
    public void AddLocalRpcTarget_ExceptionThrownWhenTargetIsNull()
    {
        var streams = Nerdbank.FullDuplexStream.CreateStreams();
        var rpc     = new JsonRpc(streams.Item1, streams.Item2);

        Assert.Throws <ArgumentNullException>(() => rpc.AddLocalRpcTarget(null));
    }
Пример #10
0
        private async Task RespondToRpcRequestsAsync(Stream stream, int clientId)
        {
            Console.WriteLine($"Connection made, clientId = {clientId}");

            var cancellationTokenSource = new CancellationTokenSource();

            var formatter = new JsonMessageFormatter(Encoding.UTF8);
            //formatter.ProtocolVersion = new Version(1, 0);

            var handler = new NewLineDelimitedMessageHandler(stream, stream, formatter)
            {
                NewLine = NewLineDelimitedMessageHandler.NewLineStyle.Lf
            };

            var jsonRpc = new JsonRpc(handler);

            jsonRpc.AddLocalRpcTarget(new Notifications(cancellationTokenSource.Token));
            jsonRpc.StartListening();

            jsonRpc.TraceSource = new TraceSource("ServerTraceSource")
            {
                Switch = new SourceSwitch("ServerSourceSwitch", "Verbose")
            };
            jsonRpc.TraceSource.Listeners.Add(new ConsoleTraceListener());

            await jsonRpc.Completion;

            cancellationTokenSource.Cancel();

            Console.WriteLine($"Connection terminated, clientId = {clientId}");
        }
Пример #11
0
        public InProcLanguageServer(Stream inputStream,
                                    Stream outputStream,
                                    AbstractRequestHandlerProvider requestHandlerProvider,
                                    CodeAnalysis.Workspace workspace,
                                    IDiagnosticService diagnosticService,
                                    IAsynchronousOperationListenerProvider listenerProvider,
                                    string?clientName)
        {
            _requestHandlerProvider = requestHandlerProvider;
            _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;
            _listener          = listenerProvider.GetListener(FeatureAttribute.LanguageServer);
            _clientName        = clientName;
            _diagnosticService.DiagnosticsUpdated += DiagnosticService_DiagnosticsUpdated;

            _clientCapabilities = new VSClientCapabilities();
        }
Пример #12
0
        internal LanguageServerTarget(
            AbstractRequestDispatcherFactory requestDispatcherFactory,
            JsonRpc jsonRpc,
            ICapabilitiesProvider capabilitiesProvider,
            ILspWorkspaceRegistrationService workspaceRegistrationService,
            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, globalOptions, supportedLanguages, userVisibleServerName, TelemetryServerName);
            Queue.RequestServerShutdown += RequestExecutionQueue_Errored;
        }
    private JsonRpc InitializeServer(JsonRpcTargetOptions?targetOptions = null)
    {
        var serverRpc = new JsonRpc(this.messageHandler);

        serverRpc.AddLocalRpcTarget(this.server, targetOptions);
        serverRpc.StartListening();
        return(serverRpc);
    }
Пример #14
0
        public async Task RespondToWebSocketRequestAsync(WebSocket webSocket, CancellationToken token)
        {
            var jsonRpc = new JsonRpc(new WebSocketMessageHandler(webSocket));

            jsonRpc.AddLocalRpcTarget(new JsonService());
            jsonRpc.StartListening();
            await jsonRpc.Completion;
        }
Пример #15
0
        internal LanguageServerTarget(
            AbstractRequestDispatcherFactory requestDispatcherFactory,
            JsonRpc jsonRpc,
            ICapabilitiesProvider capabilitiesProvider,
            LspWorkspaceRegistrationService workspaceRegistrationService,
            LspMiscellaneousFilesWorkspace?lspMiscellaneousFilesWorkspace,
            IGlobalOptionService globalOptions,
            IAsynchronousOperationListenerProvider listenerProvider,
            ILspLogger logger,
            ImmutableArray <string> supportedLanguages,
            string?clientName,
            WellKnownLspServerKinds serverKind)
        {
            _requestDispatcher = requestDispatcherFactory.CreateRequestDispatcher(serverKind);

            _capabilitiesProvider = capabilitiesProvider;
            _logger = logger;

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

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

            _queue = new RequestExecutionQueue(
                logger,
                workspaceRegistrationService,
                lspMiscellaneousFilesWorkspace,
                globalOptions,
                supportedLanguages,
                serverKind);
            _queue.RequestServerShutdown += RequestExecutionQueue_Errored;

            var entryPointMethod = typeof(DelegatingEntryPoint).GetMethod(nameof(DelegatingEntryPoint.EntryPointAsync));

            Contract.ThrowIfNull(entryPointMethod, $"{typeof(DelegatingEntryPoint).FullName} is missing method {nameof(DelegatingEntryPoint.EntryPointAsync)}");

            foreach (var metadata in _requestDispatcher.GetRegisteredMethods())
            {
                // Instead of concretely defining methods for each LSP method, we instead dynamically construct
                // the generic method info from the exported handler types.  This allows us to define multiple handlers for the same method
                // but different type parameters.  This is a key functionality to support TS external access as we do not want to couple
                // our LSP protocol version dll to theirs.
                //
                // We also do not use the StreamJsonRpc support for JToken as the rpc method parameters because we want
                // StreamJsonRpc to do the deserialization to handle streaming requests using IProgress<T>.
                var delegatingEntryPoint = new DelegatingEntryPoint(metadata.MethodName, this);

                var genericEntryPointMethod = entryPointMethod.MakeGenericMethod(metadata.RequestType, metadata.ResponseType);

                _jsonRpc.AddLocalRpcMethod(genericEntryPointMethod, delegatingEntryPoint, new JsonRpcMethodAttribute(metadata.MethodName)
                {
                    UseSingleObjectParameterDeserialization = true
                });
            }
        }
Пример #16
0
        internal LanguageServerTarget(
            AbstractLspServiceProvider lspServiceProvider,
            JsonRpc jsonRpc,
            ICapabilitiesProvider capabilitiesProvider,
            IAsynchronousOperationListenerProvider listenerProvider,
            ILspLogger logger,
            ImmutableArray <string> supportedLanguages,
            WellKnownLspServerKinds serverKind)
        {
            _capabilitiesProvider = capabilitiesProvider;
            _logger = logger;

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

            _listener = listenerProvider.GetListener(FeatureAttribute.LanguageServer);

            // Add services that require base dependencies (jsonrpc) or are more complex to create to the set manually.
            _lspServices = lspServiceProvider.CreateServices(serverKind, ImmutableArray.Create(
                                                                 CreateLspServiceInstance <ILanguageServerNotificationManager>(new LanguageServerNotificationManager(_jsonRpc)),
                                                                 CreateLspServiceInstance(logger),
                                                                 CreateLspServiceInstance <IClientCapabilitiesProvider>(this)));

            _queue = new RequestExecutionQueue(
                supportedLanguages,
                serverKind,
                _lspServices);
            _queue.RequestServerShutdown += RequestExecutionQueue_Errored;

            _requestDispatcher = _lspServices.GetRequiredService <RequestDispatcher>();

            var entryPointMethod = typeof(DelegatingEntryPoint).GetMethod(nameof(DelegatingEntryPoint.EntryPointAsync));

            Contract.ThrowIfNull(entryPointMethod, $"{typeof(DelegatingEntryPoint).FullName} is missing method {nameof(DelegatingEntryPoint.EntryPointAsync)}");

            foreach (var metadata in _requestDispatcher.GetRegisteredMethods())
            {
                // Instead of concretely defining methods for each LSP method, we instead dynamically construct the
                // generic method info from the exported handler types.  This allows us to define multiple handlers for
                // the same method but different type parameters.  This is a key functionality to support TS external
                // access as we do not want to couple our LSP protocol version dll to theirs.
                //
                // We also do not use the StreamJsonRpc support for JToken as the rpc method parameters because we want
                // StreamJsonRpc to do the deserialization to handle streaming requests using IProgress<T>.
                var delegatingEntryPoint = new DelegatingEntryPoint(metadata.MethodName, this);

                var genericEntryPointMethod = entryPointMethod.MakeGenericMethod(metadata.RequestType, metadata.ResponseType);

                _jsonRpc.AddLocalRpcMethod(genericEntryPointMethod, delegatingEntryPoint, new JsonRpcMethodAttribute(metadata.MethodName)
                {
                    UseSingleObjectParameterDeserialization = true
                });
            }
Пример #17
0
        public FullServer(IJsonRpcMessageHandler messageHandler)
        {
            Workspace = new RpcServerWorkspace();
            RegisterWithWorkspace(Workspace);

            var serverRpc = new JsonRpc(messageHandler);
            var server    = new ServerAgent(Workspace, serverRpc);

            serverRpc.AddLocalRpcTarget(server);
            ((HtmlDialogService)Workspace.DialogService).Agent = server;
            serverRpc.TraceSource.Listeners.Add(new Listener());
            Agent = server;
        }
Пример #18
0
        /// <summary> Connects an asynchronous. </summary>
        /// <remarks> 19.09.2020. </remarks>
        /// <param name="token"> A token that allows processing to be cancelled. </param>
        /// <returns> An asynchronous result. </returns>
        public async Task ConnectAsync(CancellationToken token)
        {
            if (_socket != null && _socket.State == WebSocketState.Open)
            {
                return;
            }

            if (_socket == null || _socket.State != WebSocketState.None)
            {
                _jsonRpc?.Dispose();
                _socket?.Dispose();
                _socket = new ClientWebSocket();
            }

            _connectTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
            var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, _connectTokenSource.Token);
            await _socket.ConnectAsync(_uri, linkedTokenSource.Token);

            linkedTokenSource.Dispose();
            _connectTokenSource.Dispose();
            _connectTokenSource = null;
            Logger.Debug("Connected to Websocket.");

            var formatter = new JsonMessageFormatter();

            formatter.JsonSerializer.Converters.Add(_hashTypeConverter);
            formatter.JsonSerializer.Converters.Add(_extrinsicJsonConverter);
            formatter.JsonSerializer.Converters.Add(_extrinsicStatusJsonConverter);

            _jsonRpc = new JsonRpc(new WebSocketMessageHandler(_socket, formatter));
            _jsonRpc.TraceSource.Listeners.Add(new NLogTraceListener());
            _jsonRpc.TraceSource.Switch.Level = SourceLevels.All;
            _jsonRpc.AddLocalRpcTarget(Listener, new JsonRpcTargetOptions()
            {
                AllowNonPublicInvocation = false
            });
            _jsonRpc.StartListening();
            Logger.Debug("Listening to websocket.");

            var result = await State.GetMetaDataAsync(token);

            var metaDataParser = new MetaDataParser(_uri.OriginalString, result);

            MetaData = metaDataParser.MetaData;
            Logger.Debug("MetaData parsed.");

            GenesisHash = await Chain.GetBlockHashAsync(0, token);

            Logger.Debug("Genesis hash parsed.");
        }
Пример #19
0
        async Task ExecuteServerAsync(ServerOptions opts)
        {
            m_requesters = new ConcurrentDictionary <int, IRequest>();
            m_listener   = new TcpListener(IPAddress.Parse(opts.Host), opts.Port);
            m_listener.Start();

            while (true)
            {
                try
                {
                    var conn = await m_listener.AcceptTcpClientAsync();

                    _ = Task.Run(async() =>
                    {
                        int id = Interlocked.Increment(ref s_counter);
                        try
                        {
                            var rpc          = new JsonRpc(conn.GetStream());
                            m_requesters[id] = rpc.Attach <IRequest>();

                            rpc.AddLocalRpcTarget(new Responser(id, this));

                            // Initiate JSON-RPC message processing.
                            rpc.StartListening();

                            await rpc.Completion;
                        }
                        catch (Exception) { }
                        finally
                        {
                            m_requesters.TryRemove(id, out IRequest requester);
                            conn.Close();

                            if (m_requesters.IsEmpty)
                            {
                                m_listener.Stop();
                            }

                            ((IDisposable)requester)?.Dispose();
                        }
                    });
                }
                catch (ObjectDisposedException)
                {
                    // This happens when Stop is called and we're waiting for connection.
                    break;
                }
            }
        }
Пример #20
0
        private static JsonRpc CreateJsonRpc(Stream sendingStream, Stream receivingStream, object target)
        {
            JsonMessageFormatter formatter = new JsonMessageFormatter();

            formatter.JsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

            JsonRpc jsonrpc = new JsonRpc(new HeaderDelimitedMessageHandler(sendingStream, receivingStream, formatter));

            if (target != null)
            {
                jsonrpc.AddLocalRpcTarget(target);
            }

            return(jsonrpc);
        }
Пример #21
0
    public void EventsAreNotOfferedAsTargetMethods()
    {
        Func <string, string> methodNameTransform = clrMethodName =>
        {
            Assert.NotEqual($"add_{nameof(Server.ServerEvent)}", clrMethodName);
            Assert.DoesNotContain($"get_{nameof(Server.ServerEventAccessor)}", clrMethodName);
            return(clrMethodName);
        };

        var serverRpc = new JsonRpc(this.serverStream, this.serverStream);

        serverRpc.AddLocalRpcTarget(this.server, new JsonRpcTargetOptions {
            MethodNameTransform = methodNameTransform
        });
    }
Пример #22
0
        private static JsonRpc CreateRpc(string name, Stream duplexStream)
        {
            // Create a JsonRpcMessagePackFormatter as an IJsonRpcMessageFormatter.
            var formatter = new JsonRpcMessagePackFormatter(MyCompositeResolver.Instance);

            // Create a JsonRpc that uses the IJsonRpcMessageFormatter.
            var handler = new LengthHeaderMessageHandler(duplexStream, duplexStream, formatter);
            var rpc     = new JsonRpc(handler)
            {
                TraceSource = new TraceSource(name, SourceLevels.Verbose),
            };

            rpc.AddLocalRpcTarget(new ServerObject());
            rpc.StartListening();
            return(rpc);
        }
        async Task OnStartAsync()
        {
            Log("Call ActivateAsync.");

            connection = await client.ActivateAsync(CancellationToken.None);

            if (connection == null)
            {
                throw new ApplicationException("No connection returned from ActivateAsync.");
            }

            Log("JsonRpc.StartListening.");

            var target = new LanguageClientTarget(this);

            jsonRpc = new JsonRpc(connection.Writer, connection.Reader, target);

            jsonRpc.Disconnected += JsonRpcDisconnected;

            InitializeCustomClientProviders();

            var customClient = client as ILanguageClientCustomMessage;

            if (customClient != null)
            {
                Log("Adding LanguageClientCustomMessage.");

                if (customClient.CustomMessageTarget != null)
                {
                    jsonRpc.AddLocalRpcTarget(customClient.CustomMessageTarget);
                }

                await customClient.AttachForCustomMessageAsync(jsonRpc);
            }

            jsonRpc.StartListening();
            jsonRpc.JsonSerializer.NullValueHandling = NullValueHandling.Ignore;

            InitializeResult result = await Initialize();

            ServerCapabilities = result.Capabilities;
            OnServerCapabilitiesChanged();

            await SendConfigurationSettings();
        }
        public async Task RunAsync(CancellationToken cancellationToken)
        {
            using var semaphore = new SemaphoreSlim(_maxConnection, _maxConnection);
            while (!cancellationToken.IsCancellationRequested)
            {
                await semaphore.WaitAsync(cancellationToken);

                try
                {
                    _logger.LogInformation("create pipe.");
                    var stream = new NamedPipeServerStream(_pipeName, PipeDirection.InOut, _maxConnection, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

                    _logger.LogInformation("wait for connection.");
                    await stream.WaitForConnectionAsync(cancellationToken);

                    _logger.LogInformation("create target.");
                    var rpc = new JsonRpc(stream);
                    try
                    {
                        var target = OnConnect(rpc);
                        rpc.AddLocalRpcTarget <T>(target, null);
                        rpc.StartListening();
                        rpc.Disconnected += (o, e) =>
                        {
                            _logger.LogInformation("disconnected. {reason} - {description}", e.Reason, e.Description);
                            semaphore.Release();
                        };
                    }
                    catch (Exception e)
                    {
                        _logger.LogError(e, "create target fail.");
                        semaphore.Release();
                    }
                }
                catch (Exception e)
                {
                    if (!cancellationToken.IsCancellationRequested)
                    {
                        _logger.LogError(e, "create connection fail.");
                    }
                    semaphore.Release();
                }
            }
        }
Пример #25
0
        public InProcLanguageServer(
            AbstractInProcLanguageClient languageClient,
            Stream inputStream,
            Stream outputStream,
            AbstractRequestHandlerProvider requestHandlerProvider,
            Workspace workspace,
            IDiagnosticService?diagnosticService,
            IAsynchronousOperationListenerProvider listenerProvider,
            ILspSolutionProvider solutionProvider,
            string?clientName)
        {
            _languageClient         = languageClient;
            _requestHandlerProvider = requestHandlerProvider;
            _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;
            _listener          = listenerProvider.GetListener(FeatureAttribute.LanguageServer);
            _clientName        = clientName;

            _queue = new RequestExecutionQueue(solutionProvider);
            _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;
            }
        }
Пример #26
0
        internal async Task <int> RunAsync()
        {
            Logger.LogInformation($"AzDevOpsInteractiveClient is running");

            if (_opts.WaitDebug)
            {
                while (!Debugger.IsAttached)
                {
                    Logger.LogInformation("Awaiting for an attached debugger");
                    await Task.Delay(TimeSpan.FromMilliseconds(500));
                }
            }

            try
            {
                // Create and asyncronously initialize Azure DevOps client
                var service = new AzureDevOpsCodeSearchService(LoggerFactoryInstance, _opts);
                service.InitializeAsync().FireAndForget(Logger);

                Logger.LogInformation($"Waiting for client to make a connection to pipe {_opts.RpcPipeName} for repo {_opts.ProjectUri}");
                using (var stream = new NamedPipeServerStream(_opts.RpcPipeName,
                                                              PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
                {
                    await stream.WaitForConnectionAsync();

                    using (var jsonRpc = new JsonRpc(stream))
                    {
                        jsonRpc.AddLocalRpcTarget(service);
                        jsonRpc.StartListening();
                        await jsonRpc.Completion;
                    }
                }

                Logger.LogInformation($"AzDevOpsInteractiveClient is existing");
            }
            catch (Exception e)
            {
                Logger.LogError(e, $"Failure while processing RPC requests");
                return(1);
            }

            return(0);
        }
Пример #27
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;
            }
        }
Пример #28
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);
        }
    }
Пример #29
0
        public async Task <IActionResult> Get(bool useJsonRpc)
        {
            if (!this.HttpContext.WebSockets.IsWebSocketRequest)
            {
                return(this.BadRequest());
            }

            using (var webSocket = await this.HttpContext.WebSockets.AcceptWebSocketAsync())
            {
                if (useJsonRpc)
                {
                    using (var jsonRpc = new JsonRpc(new WebSocketMessageHandler(webSocket)))
                    {
                        jsonRpc.AddLocalRpcTarget(new SocketServer());
                        jsonRpc.StartListening();
                        await jsonRpc.Completion;
                    }
                }
                else
                {
                    var buffer = new byte[100];
                    while (true)
                    {
                        var result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), CancellationToken.None);

                        if (result.CloseStatus.HasValue)
                        {
                            await webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "ok", CancellationToken.None);

                            break;
                        }

                        await webSocket.SendAsync(new ArraySegment <byte>(buffer, 0, result.Count), WebSocketMessageType.Binary, true, CancellationToken.None);
                    }
                }
            }

            return(new EmptyResult());
        }
        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(),
                });
            }