Creating LSP (Language Server Protocol) for multiple clients using RPC - visual-studio-code

I am trying to create a custom LSP.
My goal is to create one language server for both monaco editor (on web) and vscode extension.
Currently I use Node/IPC to connect the vscode-extension with the server.
and ws-jsonrpc to connect monaco editor with the server.
quoting from this article Extending a client with the language server protocol
:
There are multiple ways to use JSON-RPC, but you see these two ways in
most implementations:
Communication is done via the standard input / output, i.e., the command line interface
Communication is performed via TCP/IP, i.e., network messages similar to HTTP
I should be able to use JSON-RPC for both communication (internal communication between processes which is the vscode-extesion in my case , and external communication which is monaco-editor in my case)
Here is how I am launching the server for the moment:
For IPC communication:
const languageServer = new LanguageServer(createConnection(ProposedFeatures.all));
languageServer.start();
For 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);
});
}
});
}
})

The server that you are using should not operate with multiple clients using it at the same time. It even says: "the protocol currently assumes that one server serves one tool.". Also, maybe read this article about your topic. **https://code.visualstudio.com/api/language-extensions/language-server-extension-guide **

Related

Snapshot return array

I've created a web socket server with Node.js to connect two Flutter apps. I can post a message to server but when I listen to it on WebApp i receive an array [79,101] instead message (Oi). How can I solve it?
Sink Message
void _sendMessage(data) {
widget.channel.sink.add('Oi');
}
Cliente Stream Builder
StreamBuilder(
stream: channel.stream,
builder: (context, snapshot) {
return Text(snapshot.hasData ? '${snapshot.data}' : 'Null');
},
)
Node.js Server
const WebSocket = require('ws');
// start the server and specify the port number
const port = 8080;
const wss = new WebSocket.Server({ port: port });
console.log(`[WebSocket] Starting WebSocket server on localhost:${port}`);
wss.on('connection', (ws, request) => {
const clientIp = request.sock.remoteAddress;
console.log(`[WebSocket] Client with IP ${clientIp} has connected`);
ws.send('Connected!');
// Broadcast aka send messages to all connected clients
ws.on('message', (message) => {
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message); } })
console.log(`[WebSocket] Message ${message} was received`); });
});
This might not be the solution you are looking for but I would try and convert the response via String.fromCharCodesince the response might be ASCII characters to begin my way of debugging.

How do i use sockets in sailsjs version 1.4

I am trying to use sockets in sailsjs.
I have an action which just returns the socketId
module.exports = async function exampleAction(req, res) {
if (!req.isSocket) {
console.log("not a socket req");
return res.badRequest();
}
sails.sockets.getId(req);
return res.json({ socketid: sails.sockets.getId(req) });
};
and in routes.js:
"GET /label/exampleaction": {
action: "label/example-action",
isSocket: true,
},
I'm trying to connect to it from nuxt.js using Websocket :
this.connection = new WebSocket("ws://localhost:1337/label/exampleaction");
This gives me an error:
WebSocket connection to 'ws://localhost:1337/label/exampleaction' failed:
What am I doing wrong?
First of all, try to make this controller simpler, only for tests.
Like this:
async function onConnect(req, res) {
const socketId = sails.sockets.getId(req);
res.json(socketId);
}
'POST /connect': { controller: 'TestController', action:'onConnect' },
For client part, i recommend use the sails browser library: https://github.com/balderdashy/sails.io.js
You can use it in your nuxt app, it is all javascript, no mistery.
Sails Docs have a specific section with more details: https://sailsjs.com/documentation/reference/web-sockets/socket-client

AEDES SERVER DOES NOT CONNECT TO CLIENT

I want to make a simple client server example with visual studio code. For my mqtt client instance, mosca didn't work. So I created a server with aedes. However, it is not possible to connect to client.js at the moment. I'm sure it's missing on the server side, but I'm not sure how to fix it. I'm very new to this. my codes are below.
Server;
const aedes = require('aedes')()
const server = require('net').createServer(aedes.handle)
const httpServer = require('http').createServer()
const ws = require('websocket-stream')
const port = 1883
const wsPort = 3000
server.listen(port, function () {
console.log('server started and listening on port ', port)
})
ws.createServer({ server: httpServer }, aedes.handle)
httpServer.listen(wsPort, function () {
console.log('websocket server listening on port ', wsPort)
})
Client;
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://192.168.43.40:1883');
client.subscribe('new-user');
client.on('connect', function() {
console.log('connected!');
client.publish('new-user', 'Cansu-' + Math.ceil(Math.random() * 10));
});
client.on('message', function(topic, message) {
console.log(topic, ' : ', message.toString());
client.end();
});
Thank You!!!

React Native socket.io client connecting successfully, but emits are not received on either end

I'm trying to get communication working between a socket-io server and an iOS app. The devices connect according to both logs, but any socket.emit() actions from either the client or the server are not triggering the respective .on() event on the other end. Here is a minimal example that produces this problem.
Server code:
from aiohttp import web
import socketio
sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)
#sio.on('connect', namespace='/mp')
async def connect(sid, environ):
print("connect ", sid)
#sio.on('chat message', namespace='/mp')
async def message(sid, data):
print("message ", data)
#sio.on('disconnect', namespace='/mp')
def disconnect(sid):
print('disconnect ', sid)
if __name__ == '__main__':
web.run_app(app)
Client code (React Native app)
window.navigator.userAgent = 'ReactNative';
import React from "react"
import openSocket from "socket.io-client"
import { StyleSheet, Text, View, FlatList } from "react-native"
console.ignoredYellowBox = ["Remote debugger"]
import { YellowBox } from "react-native"
YellowBox.ignoreWarnings([
"Unrecognized WebSocket connection option(s) `agent`, `perMessageDeflate`, `pfx`, `key`, `passphrase`, `cert`, `ca`, `ciphers`, `rejectUnauthorized`. Did you mean to put these under `headers`?"
])
var app = null
var socket = openSocket("http://localhost:8080/mp", {
jsonp: false,
reconnection: true,
reconnectionDelay: 500,
reconnectionAttempts: Infinity,
transports: ["websocket"]
})
export default class App extends React.Component {
constructor(props) {
super(props)
app = this
socket.on("connect", function() {
console.log("connected")
socket.emit("message", "test")
})
}
render() {
app = this
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
marginLeft:20,
marginTop: 40,
}
})
Turns out the issue was that I was sending event message to the server, but the server was listening for event chat message (I mixed up the event name and its function). Even then, server to client communication still doesn't work so I guess it's more debugging :P

React Native Parse LiveQuery error on socket

I am having trouble connecting to the LiveQuery server that I setup on the server side of my React Native project. I followed the instructions on the site verbatim, but can only manage to get 'error on socket' when I connect with numerous attempts by the server to reconnect.
Here is my server setup:
liveQuery: {
classNames: ['BekonRequest'],
}
var port = 1337;
server.listen(port, function() {
console.log('parse-server running on port ' + port); });
var parseLiveQueryServer = ParseServer.createLiveQueryServer(server);
server.listen(port, function() {
console.log('parse-server running on port ' + port);
});
var parseLiveQueryServer = ParseServer.createLiveQueryServer(server);
And my client side code:
let requestQuery = new Parse.Query('BekonRequest');
requestQuery.equalTo("username", "broncos#nfl.com");
let subscription = requestQuery.subscribe();
subscription.on('create', (requests) => {
console.log(requests);
});
Can anyone see why I am not able to connect successfully?