【发布时间】:2021-01-08 00:59:09
【问题描述】:
我正在尝试创建自定义 LSP。 我的目标是为 monaco 编辑器(在网络上)和 vscode 扩展创建一个语言服务器。
目前我使用 Node/IPC 将 vscode-extension 与服务器连接。 和 ws-jsonrpc 连接 monaco 编辑器和服务器。
引用本文Extending a client with the language server protocol :
有多种使用 JSON-RPC 的方式,但您在 大多数实现:
- 通信是通过标准输入/输出完成的,即命令行界面
- 通过 TCP/IP 进行通信,即类似于 HTTP 的网络消息
我应该能够使用 JSON-RPC 进行两种通信(进程之间的内部通信,在我的情况下是 vscode-extesion,在我的情况下是 monaco-editor 的外部通信)
这是我目前启动服务器的方式:
对于 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);
});
}
});
}
})
【问题讨论】:
-
服务器不应同时与“使用 RPC 的多个客户端”一起操作。 protocol 明确指出“[t]he 协议当前假定一台服务器服务于一种工具。”而且我怀疑 VSCode 有添加锁定的钩子。 LSP 服务器的 VSCode 扩展所需的代码只需约 100 行 Typescript、约 100 行 project.json 和约 10 行 tsconfig.json 即可完成。您必须将其设置为使用套接字。我使用标准输入/输出,但两者基本相同。
-
是的,我知道一个服务器不能操作多个客户端。那不是我的问题。我愿意启动多个服务器。但据我了解,json-RPC 连接可以与套接字或标准输入一起使用。换句话说,它可以预期这两种连接。
标签: visual-studio-code monaco-editor language-server-protocol