Closed palkerecsenyi closed 2 years ago
Hey @palkerecsenyi , did you find a fix for this issue?
Thank you for the report. This project is no longer active. If you are using the Python language server in VSCode, the language server you are using is Pylance and please the http://github.com/microsoft/pylance-release to report issues.
If you are using Visual Studio, then, please use http://github.com/microsoft/PTVS to report issues.
thank you
Environment data
Expected behaviour
I'm trying to set up Python Language Server to connect to an instance of the Monaco editor running on a website. The server doesn't have the code stored on it, and I'm using
monaco-languageclient
to send the user's Python code as an in-memory file. I'd like the frontend Monaco editor to support Python Language Server's LSP functionality.Actual behaviour
I get the following error message the moment the Monaco editor loads:
Logs
There is nothing else logged on the server.
Code Snippet / Additional information
React frontend
```typescript import { CloseAction, createConnection, ErrorAction, MonacoLanguageClient, MonacoServices, } from 'monaco-languageclient'; import { listen, MessageConnection } from 'vscode-ws-jsonrpc'; import getEnvVariable from './getEnv'; import { TaskLanguage } from '../types'; function createLanguageClient(connection: MessageConnection) { return new MonacoLanguageClient({ name: 'lsp.palcode.dev', clientOptions: { documentSelector: ['python', 'shell'], errorHandler: { error: () => ErrorAction.Continue, closed: () => CloseAction.DoNotRestart, } }, connectionProvider: { get(errorHandler, closeHandler) { return Promise.resolve(createConnection( // @ts-ignore connection, errorHandler, closeHandler, )); } } }); } type DisposeFunction = () => void; export default function connectToLanguageServer( language: TaskLanguage, ): undefined | DisposeFunction { const lspURL = getEnvVariable('LSP'); if (!lspURL) { return; } try { MonacoServices.get(); } catch (e) { // @ts-ignore MonacoServices.install(require('monaco-editor-core/esm/vs/platform/commands/common/commands').CommandsRegistry); } // in this case, language is 'python' const webSocket = new WebSocket(lspURL + '/' + language); webSocket.onerror = () => {}; let pingInterval: number; listen({ webSocket, onConnection: (connection) => { const client = createLanguageClient(connection); const disposable = client.start(); connection.onClose(() => disposable.dispose()); connection.onError(() => {}); pingInterval = window.setInterval(() => { webSocket.send('ping'); }, 20000); }, }); return () => { try { webSocket.close(); clearInterval(pingInterval); } catch (e) {} }; } ```Node.JS backend
```typescript import * as http from 'http'; import ws from 'ws'; import * as url from 'url'; import * as rpc from 'vscode-ws-jsonrpc'; import * as server from 'vscode-ws-jsonrpc/lib/server'; import * as lsp from 'vscode-languageserver'; function launch(socket: rpc.IWebSocket, command: string, args: string[]) { const reader = new rpc.WebSocketMessageReader(socket); const writer = new rpc.WebSocketMessageWriter(socket); const socketConnection = server.createConnection(reader, writer, () => socket.dispose()); const serverConnection = server.createServerProcess('JSON', command, args); server.forward(socketConnection, serverConnection, message => { if (rpc.isRequestMessage(message)) { if (message.method === lsp.InitializeRequest.type.method) { const initializeParams = message.params; initializeParams.processId = process.pid; } } return message; }); } const httpServer = http.createServer((req, res) => { // required for health checks res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write(''); res.end(); }).listen(process.env.PORT); const socketServers: { [path: string]: ws.Server, } = {}; const languages = [ { command: '/opt/python-language-server/output/bin/Release/Microsoft.Python.LanguageServer', args: [], path: '/python', }, { command: 'bash-language-server', args: ['start'], path: '/bash', }, ]; for (const language of languages) { const socket = new ws.Server({ perMessageDeflate: false, noServer: true, }); socket.on('connection', (client) => { const iWebSocket = { send: (content: any) => client.send(content), onMessage: (cb: (message: ws.Data) => void) => client.onmessage = event => { if (event.data !== 'ping') { cb(event.data); } }, onError: (cb: (message: string) => void) => client.onerror = event => { if ('message' in event) { cb(event.message) } }, onClose: (cb: (code: number, reason: string) => void) => client.onclose = event => cb(event.code, event.reason), dispose: () => client.close(), }; launch(iWebSocket, language.command, language.args); }); socketServers[language.path] = socket; } httpServer.on('upgrade', (request, socket, head) => { const pathname = url.parse(request.url).pathname; if (!pathname) { socket.destroy(); return; } const socketServer = socketServers[pathname]; if (!socketServer) { socket.destroy(); return; } socketServer.handleUpgrade(request, socket, head, (ws) => { socketServer.emit('connection', ws, request); }); }); ```