Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can not connect Language Server using socket connection #3342

Closed
masterSunflowers opened this issue Dec 8, 2024 · 5 comments
Closed

Can not connect Language Server using socket connection #3342

masterSunflowers opened this issue Dec 8, 2024 · 5 comments
Labels

Comments

@masterSunflowers
Copy link

As I see in the docs, the language server can connect to client using socket. I already create a client and start it, waiting for Language Server to connect flowing the docs, change -DCLIENT_PORT to the port of client. However, after all, language server don't connect to client.

@rgrunber
Copy link
Contributor

rgrunber commented Dec 10, 2024

At https://rgrunber.github.io/vscode/java/lsp/language/server/2023/09/18/talk-to-language-server.html I wrote an article about interacting with the language server including how to go about sending message. That was done with the convention of starting the language server first, and then connecting the client.

However, if you want to start the client first, and have it listen for the connecting language server, that can be done as well.

Just do it in reverse order, and omit the flags : -Dsocket.stream.debug=true & -Dosgi.dev

So something like :

$ socat - TCP4-LISTEN:5036

(or whichever client you're using, that is capable of listening on a port for connections)

followed by :

CLIENT_PORT=5036 ./org.eclipse.jdt.ls.product/target/repository/bin/jdtls

CLIENT_PORT could also be passed in as a system property from what I can see. Do you have the full commandline you're running in the case where this doesn't work ?

@masterSunflowers
Copy link
Author

I follow up this repository README.md file and the command are something like:

java \
	-Declipse.application=org.eclipse.jdt.ls.core.id1 \
	-Dosgi.bundles.defaultStartLevel=4 \
	-Declipse.product=org.eclipse.jdt.ls.core.product \
	-Dlog.level=ALL \
	-Xmx1G \
	--add-modules=ALL-SYSTEM \
	--add-opens java.base/java.util=ALL-UNNAMED \
	--add-opens java.base/java.lang=ALL-UNNAMED \
	-jar ./plugins/org.eclipse.equinox.launcher_1.5.200.v20180922-1751.jar \
	-configuration ./config_linux \
	-data /path/to/data \
        -DCLIENT_PORT=9000

I have created a socket port 9000 in a client and then run this command, but server cannot connect to that socket. Now, I have resolved problem by set directly environment variable DCLIENT_PORT=9000, so that it works.

@masterSunflowers
Copy link
Author

A small additional request: Could you write documentation about the parameters and options for running the language server, as well as the messages that the language server sends back to the client when it starts and after receiving a request? I have tried it and noticed that the server returns many messages in addition to the response message. Without documentation on this part, it is very difficult for users like me to use. For example, I currently do not know when the server has finished sending all messages to trigger an event to start sending the next request. Thank you very much.

@rgrunber
Copy link
Contributor

I don't think adding -DCLIENT_PORT=9000 being passed at the very end would work. You would need to pass it with all the other -D parameters. In other words, before the -jar call. This is because it needs to be passed to the JVM itself to be set as a system property. Placing it at the end passes it to JDT-LS, but that isn't what handles the -D flags. I've just tried this and that seems to be the case.

A lot of the interaction is goverened by the language server specification : https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/ . It describes the protocol itself, every kind of request a client can make and the expected response. Messages that can be sent by either client/server that do not require a response are basically notifications and many are described there.

Can you given an example of what you mean by "when the server has finished sending all messages to trigger an event to start sending the next request."

Do you mean, how to know whether the language server has finished processing a given request, and that another can be sent ? The language server can handle multiple requests simultaneously. It can even respond out of order in some instances. See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#messageOrdering . This is probably implemented through the fact that each request has a unique ID, which the server uses in the response so that the client may track which response goes with a given request.

@masterSunflowers
Copy link
Author

Thank you for your enthusiastic support! Based on the information you provided, I believe I can resolve my issue with this repository. Regarding the example of "triggering an event when the server has finished sending all messages to start sending the next request," I’m developing a program that uses the LSP programmatically rather than within an editor. In my case, my logic requires sending requests sequentially to the server, ensuring that I only initiate a new request once the previous one has been fully processed. To achieve this, I need to confirm when the server has completed handling the current request. However, I think I can implement a message handler to manage this effectively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants