0

I am using the csharp-language-server-protocol implementation to create a custom language server and it works great (see LSP).

The only problem is that I am not finding a nice way to connect the in/out streams the server uses to a websocket using .Net (I want it to work as a remote language server so I can connect to it using web sockets).

I have done my own connector and it works:

  • it gets the messages from the web socket and writes them into the input stream
  • it reads the messages from the output stream and sends them through the web socket

But I am sure there must be an existing solution that I am not managing to find.

I tried with vs-streamjsonrpc but I don't think that's what I need.

I also tried with Nerdbank.Streams#AsStream with no luck (see exception below):

(...)
var websocket = await context.WebSockets.AcceptWebSocketAsync();
var inOutStream = webSocket.AsStream();
var languageServer = await LanguageServer.From(options => options
    .WithInput(inOutStream)
    .WithOutput(inOutStream)
    ...

System.ArgumentException: 'Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.'

This exception was originally thrown at this call stack:
    System.ThrowHelper.ThrowArraySegmentCtorValidationFailedExceptions(System.Array, int, int)
    Nerdbank.Streams.WebSocketStream.ReadAsync(byte[], int, int, System.Threading.CancellationToken)
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
    Nerdbank.Streams.WebSocketStream.Read(byte[], int, int)
    OmniSharp.Extensions.JsonRpc.InputHandler.ProcessInputStream()
    System.Threading.ThreadHelper.ThreadStart_Context(object)

Does anyone have an example? Any hints?

centellenc
  • 21
  • 4
  • 1
    None of the editors currently use LSP over websocket, so you should expect no other implementation is in a hurry to support that. You are probably the one and only in this area. Remote solution such as VSCode Remote uses a different architecture, so LSP over websocket is not used there. – Lex Li Jun 08 '20 at 17:23
  • 1
    I would think that the nerd bank streams would do the "right" thing for a websocket. We don't currently have any integration tests using websockets, but it is on my list to try and add some example scenarios that use named pipes, sockets, web sockets as well. There is the https://github.com/TypeFox/monaco-languageclient that allows for lsp over ws. I have some old code that worked, but it cheated a little bit by using a node process in the middle to connect the two together https://github.com/david-driscoll/lsp-playing/tree/master/monaco/lib. – David Driscoll Jun 08 '20 at 18:56
  • @Lex Li: Maybe it makes sense that no one is trying to use websockets with the C# implementations of the LSP. But I believe I have seen Node implementations connecting the language server with web sockets and i guess that's the way to go for editors running in web applications. – centellenc Jun 09 '20 at 12:01
  • @David Driscoll: I have added some details of the test I did with Nerdbank. Maybe there is a better approach but I believe the problem is related to not having message bounderies (see comment in [Message Boundaries](https://github.com/AArnott/Nerdbank.Streams/blob/master/doc/AsStream.md#message-boundaries)). – centellenc Jun 09 '20 at 12:02
  • (sorry for late reply) message boundaries should not matter because the protocol defines an HTTP-like header system, as long as all the bytes make it, in order, then the parser will pull the content-length from the headers and parse the json from that. – David Driscoll Dec 15 '20 at 12:24
  • @centellenc did you have success in implementing this? maybe you've got a online sample? – user1237393 Jan 18 '21 at 20:12
  • @user1237393 (sorry for the late reply) Nope, we finally discarded this approach and I didn't investigate further. I don't have access to the PoC I did anymore either. – centellenc Sep 11 '21 at 01:03

0 Answers0