Où écoute le serveur Golang jsonrpc2 ? C'est un problème que de nombreux développeurs Golang rencontrent souvent lorsqu'ils utilisent le protocole jsonrpc2. Dans Golang, l'endroit où le serveur jsonrpc2 écoute dépend de la façon dont le code est implémenté. Une pratique courante consiste à demander au serveur d'écouter sur un port spécifique afin de recevoir les requêtes des clients. De plus, le serveur peut également être surveillé sur une interface réseau spécifique, telle que l'interface de bouclage locale (localhost) ou une adresse IP spécifiée. Afin de garantir que le serveur puisse écouter les requêtes et les traiter normalement, les développeurs doivent spécifier clairement l'emplacement d'écoute dans le code.
Je souhaite créer un simple serveur lsp en golang, voici le code que j'ai écrit jusqu'à présent :
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()) }
Cela fonctionne, mais je ne sais pas sur quel port il fonctionne, ni comment l'appeler via le client en général. Quelqu'un a-t-il une idée?
Je pensais que c'était le port 4389, mais ce n'est pas ça
J'utilise ce script pour tester :
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))
Je pense que c'est correct car j'ai obtenu ce client à partir d'une autre question de stackoverflow
Je comprends :
handlerwitherror(s.handle) // create a new jsonrpc2 stream server <-jsonrpc2.newconn( context.background(), jsonrpc2.newbufferedstream(os.stdin, jsonrpc2.vscodeobjectcodec{}), handler).disconnectnotify() }
Cela signifie que votre code utilise json-rpc via une entrée et une sortie standard (stdin/stdout), au lieu de connexion via le réseau.
Lorsque vous utilisez l'argument de os.stdin
作为 jsonrpc2.newbufferedstream
, vous spécifiez que l'entrée doit provenir de l'entrée standard du processus exécutant le serveur. et la réponse sera envoyée à la sortie standard.
Le serveur n’écoute donc sur aucun port réseau. Il interagit avec les données envoyées directement à ses entrées et sorties standard. Ceci est généralement utilisé pour la communication inter-processus, par exemple lorsque vous souhaitez qu'un processus appelle un processus serveur et reçoive une réponse.
Par exemple, voir « go : Communication bidirectionnelle avec un autre processus ? » ou davidelorenzoli/stdin-stdout-ipc
.
Si vous souhaitez que le serveur json-rpc écoute sur un port réseau, vous devez utiliser le net
package. Vous devrez également modifier le script client pour envoyer ses requêtes au bon port réseau au lieu d'envoyer une requête http à l'url.
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 }
Ceci est un exemple de base où la méthode serve
crée un écouteur TCP écoutant sur le port 4389 de localhost. Il entre ensuite dans une boucle en attente d'une connexion, et lorsqu'il obtient une connexion, il démarre une nouvelle goroutine pour gérer la connexion à l'aide du serveur json-rpc.
Côté client, vous devez ouvrir une connexion TCP au serveur, écrire la requête json-rpc sur cette connexion, puis lire la réponse.
Vous ne pouvez pas utiliser la requests
bibliothèque comme dans un script python, car elle est destinée aux requêtes http, pas aux connexions TCP brutes.
Vous devrez utiliser la socket
bibliothèque en python, ou dans la langue de votre client, pour créer une connexion TCP et envoyer/recevoir des données via celle-ci.
Mais rappelez-vous, lsp (Language Server Protocol) fonctionne sur stdin/stdout et non sur les sockets réseau.
En effet, le serveur lsp est généralement démarré en tant que processus enfant par l'éditeur/IDE et communique directement via ces canaux. Ainsi, en fonction de votre cas d'utilisation, les méthodes brutes stdin/stdout peuvent être plus appropriées.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!