Создание LSP (протокол языкового сервера) для нескольких клиентов с использованием RPC

Я пытаюсь создать собственный LSP. Моя цель - создать один языковой сервер для редактора monaco (в Интернете) и расширения vscode.

В настоящее время я использую Node / IPC для подключения расширения vscode к серверу. и ws-jsonrpc для подключения редактора monaco к серверу.

цитата из этой статьи Расширение клиента с помощью протокола языкового сервера:

Есть несколько способов использования JSON-RPC, но в большинстве реализаций вы видите эти два:

  • Связь осуществляется через стандартный ввод / вывод, т. Е. Через интерфейс командной строки.
  • Связь осуществляется через TCP / IP, т. Е. Сетевые сообщения, аналогичные HTTP.

Я должен иметь возможность использовать JSON-RPC как для связи (внутренняя связь между процессами, которая является расширением vscode в моем случае, так и внешняя связь, которая в моем случае является редактором monaco)

Вот как я сейчас запускаю сервер:

Для связи IPC:

const languageServer = new LanguageServer(createConnection(ProposedFeatures.all));
languageServer.start();

Для WebSocket RPC:

import * as express from "express";
import * as ws from "ws";

import * as rpc from "vscode-ws-jsonrpc";
import * as url from "url";
import * as http from "http";
import * as net from "net";

const app = express();
const server = app.listen(3000);
const wss = new ws.Server({
    noServer: true,
    perMessageDeflate: false
});

function launch(socket : rpc.IWebSocket ){
    const reader = new rpc.WebSocketMessageReader(socket);
    const writer = new rpc.WebSocketMessageWriter(socket);
    const languageServer = new LanguageServer(createConnection(reader, writer));
    languageServer.start();
    
}
server.on('upgrade', (request: http.IncomingMessage, socket: net.Socket, head: Buffer) => {
    const pathname = request.url ? url.parse(request.url).pathname : undefined;
    console.log("server on upgrade ", pathname);

    if (pathname === '/sampleServer') {
        wss.handleUpgrade(request, socket, head, (webSocket: any) => {

            const socket: rpc.IWebSocket = {
                send: (content: any) => webSocket.send(content, (error: any) => {
                    if (error) {
                        throw error;
                    }
                }),
                onMessage: (cb: any) => webSocket.on('message', cb),
                onError: (cb: any) => webSocket.on('error', cb),
                onClose: (cb: any) => webSocket.on('close', cb),
                dispose: () => webSocket.close()
            };
            // launch the server when the web socket is opened
            if (webSocket.readyState === webSocket.OPEN) {
                launch(socket); 
            } else {
                webSocket.on('open', () => {
                    launch(socket); 
                });
            }
        });
    }
})

person Rami ZK    schedule 21.09.2020    source источник
comment
Можете ли вы прочитать code.visualstudio.com/api/language-extensions /?   -  person Rayees AC    schedule 24.09.2020
comment
Сервер не должен работать с несколькими клиентами, использующими RPC одновременно. В протоколе конкретно указывается [t] он протокол в настоящее время предполагается, что один сервер обслуживает один инструмент. И я сомневаюсь, что у VSCode есть крючки для добавления блокировки. Код, необходимый для расширения VSCode для вашего LSP-сервера, может быть выполнен только с ~ 100 строками Typescript, ~ 100 строками в project.json и ~ 10 строками tsconfig.json. Вам нужно будет настроить его для использования сокетов. Я использую stdin / out, но в основном это одно и то же.   -  person kaby76    schedule 26.09.2020
comment
Да, я знаю, что сервер не должен работать с несколькими клиентами. это не мой вопрос. Я хочу запустить несколько серверов. но, как я понял, соединение json-RPC может работать с сокетом или stdin. другими словами, он может ожидать двух видов связи.   -  person Rami ZK    schedule 27.09.2020


Ответы (1)


Сервер, который вы используете, не должен работать с несколькими клиентами, использующими его одновременно. Он даже говорит: протокол в настоящее время предполагает, что один сервер обслуживает один инструмент .. Также, возможно, прочтите эту статью по вашей теме. ** https://code.visualstudio.com/api/language-extensions/language-server-extension-guide **

person Promaster1    schedule 30.09.2020