文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Golang jsonrpc2 服务器在哪里监听?

2024-02-08 21:07

关注

Golang jsonrpc2 服务器在哪里监听?这是许多Golang开发者在使用jsonrpc2协议时经常遇到的问题。在Golang中,jsonrpc2服务器监听的位置取决于代码的实现方式。一种常见的做法是将服务器监听在特定的端口上,以便接收来自客户端的请求。另外,也可以将服务器监听在特定的网络接口上,例如本地回环接口(localhost)或指定的IP地址上。为了确保服务器能够正常监听请求并进行处理,开发者需要在代码中明确指定监听的位置。

问题内容

我想在golang中创建一个简单的lsp服务器,到目前为止这是我编写的代码:

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

}

它可以运行,但我不知道它在哪个端口上运行,或者一般如何通过客户端调用它。有人有什么想法吗?

我认为应该是端口4389,但不是那个

我正在使用此脚本进行测试:

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

我认为这是正确的,因为我从另一个 stackoverflow 问题中获取了这个客户

解决方法

我明白了:

handlerwitherror(s.handle)

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

这意味着您的代码通过标准输入和输出(stdin/stdout)使用 json-rpc,而不是通过网络连接。
当您使用 os.stdin 作为 jsonrpc2.newbufferedstream 的参数时,您指定输入应来自运行服务器的进程的标准输入。并且响应将被发送到标准输出。

因此,服务器没有侦听任何网络端口。它与直接发送到其标准输入和输出的数据进行交互。这通常用于进程间通信,例如,当您希望一个进程调用服务器进程并接收响应时。
例如,请参阅“go:与另一个进程进行双向通信?”或davidelorenzoli/stdin-stdout-ipc

如果您希望 json-rpc 服务器侦听网络端口,则需要使用 net 包。您还需要修改客户端脚本以将其请求发送到正确的网络端口,而不是向 url 发送 http 请求。

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
}

这是一个基本示例,其中 serve 方法创建一个 tcp 侦听器,侦听本地主机的端口 4389。然后它进入一个等待连接的循环,当它获得连接时,它会启动一个新的 goroutine 来使用 json-rpc 服务器处理该连接。

在客户端,您需要打开到服务器的 tcp 连接,将 json-rpc 请求写入该连接,然后读取响应。

您不能像在 python 脚本中那样使用 requests 库,因为它用于 http 请求,不是原始 tcp 连接。
您将需要在 python 中使用 socket 库,或在您客户端的语言,以创建 tcp 连接并通过它发送/接收数据。

但请记住,lsp(语言服务器协议) 通过 stdin/stdout 运行而不是网络套接字。
这是因为 lsp 服务器通常由编辑器/ide 作为子进程启动,并通过这些通道直接通信。因此,根据您的用例,原始的 stdin/stdout 方法可能更合适。

以上就是Golang jsonrpc2 服务器在哪里监听?的详细内容,更多请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-服务器
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯