Wo hört der Golang jsonrpc2-Server zu? Dies ist ein Problem, auf das viele Golang-Entwickler häufig stoßen, wenn sie das jsonrpc2-Protokoll verwenden. Wo in Golang der jsonrpc2-Server lauscht, hängt davon ab, wie der Code implementiert wird. Eine gängige Praxis besteht darin, den Server einen bestimmten Port überwachen zu lassen, um Anfragen von Clients zu empfangen. Darüber hinaus kann der Server auch auf einer bestimmten Netzwerkschnittstelle überwacht werden, beispielsweise der lokalen Loopback-Schnittstelle (localhost) oder einer angegebenen IP-Adresse. Um sicherzustellen, dass der Server Anfragen abhören und normal verarbeiten kann, müssen Entwickler den Abhörort im Code klar angeben.
Ich möchte einen einfachen LSP-Server in Golang erstellen. Dies ist der Code, den ich bisher geschrieben habe:
package main import ( "context" "fmt" "os" "sync" "github.com/sourcegraph/jsonrpc2" ) type lspserver struct { // the symmetric connection conn jsonrpc2.conn // check if the connection is available connmutex sync.mutex // shutdown shutdown bool } func newlspserver() *lspserver { return &lspserver{} } func (s *lspserver) initialize(ctx context.context) error { // to implement return nil } func (s *lspserver) handle(context.context, *jsonrpc2.conn, *jsonrpc2.request) (result interface{}, err error) { fmt.println("handling request...") // to implement return nil, nil } func (s *lspserver) serve(ctx context.context) { fmt.println("starting lsp server...") // what port is this server listening on? // it is listening on port 4389 // create a new jsonrpc2 stream server handler := jsonrpc2.handlerwitherror(s.handle) // create a new jsonrpc2 stream server <-jsonrpc2.newconn( context.background(), jsonrpc2.newbufferedstream(os.stdin, jsonrpc2.vscodeobjectcodec{}), handler).disconnectnotify() } func main() { // create a new lsp server server := newlspserver() server.serve(context.background()) }
Es funktioniert, aber ich weiß nicht, auf welchem Port es läuft, oder wie ich es generell über den Client aufrufen soll. Hat jemand irgendwelche Ideen?
Ich dachte, es wäre Port 4389, aber das ist es nicht
Ich verwende dieses Skript zum Testen:
import json import requests def rpc_call(url, method, args): headers = {'content-type': 'application/json'} payload = { "method": method, "params": [args], "jsonrpc": "2.0", "id": 1, } response = requests.post(url, data=json.dumps(payload), headers=headers).json() return response['result'] url = 'http://localhost:4389/' emailArgs = {'To': '[email protected]','Subject': 'Hello', 'Content': 'Hi!!!'} smsArgs = {'Number': '381641234567', 'Content': 'Sms!!!'} print(rpc_call(url, 'email.SendEmail', emailArgs)) print(rpc_call(url, 'sms.SendSMS', smsArgs))
Ich denke, das ist richtig, weil ich diesen Client von einer anderen Stackoverflow-Frage erhalten habe
Ich verstehe:
handlerwitherror(s.handle) // create a new jsonrpc2 stream server <-jsonrpc2.newconn( context.background(), jsonrpc2.newbufferedstream(os.stdin, jsonrpc2.vscodeobjectcodec{}), handler).disconnectnotify() }
Das bedeutet, dass Ihr Code JSON-RPC über die Standardeingabe und -ausgabe (stdin/stdout) verwendet, anstatt eine Verbindung über das Netzwerk herzustellen.
Wenn Sie das Argument für os.stdin
作为 jsonrpc2.newbufferedstream
verwenden, geben Sie an, dass die Eingabe von der Standardeingabe des Prozesses stammen soll, der den Server ausführt. und die Antwort wird an die Standardausgabe gesendet.
Der Server überwacht also keinen Netzwerkport. Es interagiert mit Daten, die direkt an seine Standardeingabe und -ausgabe gesendet werden. Dies wird normalerweise für die Kommunikation zwischen Prozessen verwendet, wenn Sie beispielsweise möchten, dass ein Prozess einen Serverprozess aufruft und eine Antwort erhält.
Siehe zum Beispiel „go: Zwei-Wege-Kommunikation mit einem anderen Prozess? “ oder davidelorenzoli/stdin-stdout-ipc
.
Wenn Sie möchten, dass der JSON-RPC-Server einen Netzwerkport überwacht, müssen Sie das net
-Paket verwenden. Sie müssen außerdem das Client-Skript ändern, um seine Anfragen an den richtigen Netzwerkport zu senden, anstatt eine http-Anfrage an die URL zu senden.
package main import ( "context" "net" "log" "sync" "github.com/sourcegraph/jsonrpc2" ) type LSPServer struct { // The symmetric connection conn jsonrpc2.Conn // Check if the connection is available connMutex sync.Mutex // shutdown shutdown bool } func NewLSPServer() *LSPServer { return &LSPServer{} } func (s *LSPServer) Initialize(ctx context.Context) error { // Initialize here if needed return nil } func (s *LSPServer) Handle(context.Context, *jsonrpc2.Conn, *jsonrpc2.Request) (result interface{}, err error) { fmt.Println("Handling request...") // Handle something return nil, nil } func (s *LSPServer) Serve(ctx context.Context) { fmt.Println("Starting LSP server...") // Listen on TCP port 4389 on all available unicast and // anycast IP addresses of the local system. l, err := net.Listen("tcp", "localhost:4389") if err != nil { log.Fatal(err) } defer l.Close() for { // Wait for a connection. conn, err := l.Accept() if err != nil { log.Fatal(err) } // Handle the connection in a new goroutine. go func(c net.Conn) { // Create a new jsonrpc2 stream server handler := jsonrpc2.HandlerWithError(s.Handle) <-jsonrpc2.NewConn( ctx, jsonrpc2.NewBufferedStream(c, jsonrpc2.VSCodeObjectCodec{}), handler).DisconnectNotify() c.Close() }(conn) } } func main() { // Create a new LSP server server := NewLSPServer() go server.Serve(context.Background()) // run Serve in a separate goroutine select {} // wait forever }
Dies ist ein einfaches Beispiel, bei dem die serve
-Methode einen TCP-Listener erstellt, der Port 4389 von localhost überwacht. Anschließend tritt es in eine Schleife ein und wartet auf eine Verbindung. Wenn eine Verbindung hergestellt wird, startet es eine neue Goroutine, um die Verbindung mithilfe des JSON-RPC-Servers zu verarbeiten.
Auf der Clientseite müssen Sie eine TCP-Verbindung zum Server öffnen, die JSON-RPC-Anfrage an diese Verbindung schreiben und dann die Antwort lesen.
Sie können die requests
Bibliothek nicht wie in einem Python-Skript verwenden, da sie für http-Anfragen und nicht für rohe TCP-Verbindungen gedacht ist.
Sie müssen die socket
-Bibliothek in Python oder in der Sprache Ihres Kunden verwenden, um eine TCP-Verbindung herzustellen und darüber Daten zu senden/empfangen.
Aber denken Sie daran, lsp (Language Server Protocol) läuft über stdin/stdout und nicht über Netzwerk-Sockets.
Dies liegt daran, dass der LSP-Server normalerweise vom Editor/IDE als untergeordneter Prozess gestartet wird und direkt über diese Kanäle kommuniziert. Abhängig von Ihrem Anwendungsfall sind die rohen stdin/stdout-Methoden möglicherweise besser geeignet.
Das obige ist der detaillierte Inhalt vonWo hört der Golang jsonrpc2-Server zu?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!