Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Di manakah pelayan jsonrpc2 Golang mendengar?

Di manakah pelayan jsonrpc2 Golang mendengar?

王林
王林ke hadapan
2024-02-08 21:27:28762semak imbas

Golang jsonrpc2 服务器在哪里监听?

Di manakah pelayan jsonrpc2 Golang mendengar? Ini adalah masalah yang sering dihadapi oleh ramai pembangun Golang apabila menggunakan protokol jsonrpc2. Di Golang, tempat pelayan jsonrpc2 mendengar bergantung pada cara kod itu dilaksanakan. Amalan biasa ialah meminta pelayan mendengar pada port tertentu untuk menerima permintaan daripada pelanggan. Selain itu, pelayan juga boleh dipantau pada antara muka rangkaian tertentu, seperti antara muka gelung balik tempatan (localhost) atau alamat IP tertentu. Untuk memastikan pelayan boleh mendengar permintaan dan memprosesnya secara normal, pembangun perlu menyatakan dengan jelas lokasi mendengar dalam kod.

Kandungan soalan

Saya ingin membuat pelayan lsp mudah di golang, ini adalah kod yang saya tulis setakat ini:

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())

}

Ia berfungsi, tetapi saya tidak tahu port mana yang ia sedang berjalan, atau cara memanggilnya melalui pelanggan secara umum. Adakah sesiapa mempunyai sebarang idea?

Saya fikir ia adalah port 4389, tetapi bukan itu

Saya menggunakan skrip ini untuk menguji:

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&#160;protected]','Subject': 'Hello', 'Content': 'Hi!!!'}
smsArgs = {'Number': '381641234567', 'Content': 'Sms!!!'}
print(rpc_call(url, 'email.SendEmail', emailArgs))
print(rpc_call(url, 'sms.SendSMS', smsArgs))

Saya rasa ini betul kerana saya mendapat pelanggan ini daripada soalan stackoverflow yang lain

Penyelesaian

Saya faham:

handlerwitherror(s.handle)

    // create a new jsonrpc2 stream server
    <-jsonrpc2.newconn(
        context.background(),
        jsonrpc2.newbufferedstream(os.stdin, jsonrpc2.vscodeobjectcodec{}),
        handler).disconnectnotify()
}

Ini bermakna kod anda menggunakan json-rpc melalui input dan output standard (stdin/stdout), bukannya menyambung melalui rangkaian.
Apabila anda menggunakan hujah untuk os.stdin 作为 jsonrpc2.newbufferedstream , anda menentukan bahawa input harus datang daripada input standard proses yang menjalankan pelayan. dan respons akan dihantar ke output standard.

Jadi pelayan tidak mendengar pada mana-mana port rangkaian. Ia berinteraksi dengan data yang dihantar terus ke input dan output standardnya. Ini biasanya digunakan untuk komunikasi antara proses, contohnya apabila anda mahu satu proses memanggil proses pelayan dan menerima respons.
Contohnya, lihat "go: Komunikasi dua hala dengan proses lain? " atau davidelorenzoli/stdin-stdout-ipc.

Jika anda mahu pelayan json-rpc mendengar pada port rangkaian, anda perlu menggunakan pakej net. Anda juga perlu mengubah suai skrip klien untuk menghantar permintaannya ke port rangkaian yang betul dan bukannya menghantar permintaan http ke 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
}

Ini ialah contoh asas di mana kaedah serve mencipta pendengar tcp yang mendengar pada port 4389 localhost. Ia kemudian memasuki gelung menunggu sambungan, dan apabila ia mendapat sambungan ia memulakan goroutine baharu untuk mengendalikan sambungan menggunakan pelayan json-rpc.

Di sisi klien, anda perlu membuka sambungan tcp ke pelayan, tulis permintaan json-rpc ke sambungan itu, dan kemudian baca respons.

Anda tidak boleh menggunakan perpustakaan requests seperti dalam skrip python, kerana ia adalah untuk permintaan http, bukan sambungan tcp mentah.
Anda perlu menggunakan socket perpustakaan dalam python, atau dalam bahasa pelanggan anda, untuk membuat sambungan tcp dan menghantar/menerima data di atasnya.

Tetapi ingat, lsp (Protokol Pelayan Bahasa) berjalan di atas stdin/stdout dan bukan soket rangkaian.
Ini kerana pelayan lsp biasanya dimulakan sebagai proses kanak-kanak oleh editor/IDE dan berkomunikasi secara langsung melalui saluran ini. Jadi bergantung pada kes penggunaan anda, kaedah stdin/stdout mentah mungkin lebih sesuai.

Atas ialah kandungan terperinci Di manakah pelayan jsonrpc2 Golang mendengar?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam