Golang类似RPyC的库有哪些

Golang类似RPyC的库有哪些 Go 生态系统中是否有类似 RPyC 的工具,可以让我远程且无缝地执行代码?与 Python 中加载脚本的方式不同,理想情况下,执行服务器会加载一个单独的 Go DLL,并且其导出内容在客户端可见。

这适用于 Windows 环境,我希望为非 Go 宿主应用程序(例如 .NET 应用程序)构建 Go DLL。据我所知,Go 仍然不允许从非 Go 宿主加载多个 Windows DLL。

谢谢。

1 回复

更多关于Golang类似RPyC的库有哪些的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go生态系统中,确实有类似RPyC的远程代码执行工具,但需要根据你的具体需求选择合适的方案。以下是几个主要选项:

1. net/rpc (标准库)

Go标准库内置了RPC支持,可以实现远程方法调用。

// 服务器端
package main

import (
    "net"
    "net/rpc"
)

type Arith struct{}

func (t *Arith) Multiply(args *Args, reply *int) error {
    *reply = args.A * args.B
    return nil
}

func main() {
    arith := new(Arith)
    rpc.Register(arith)
    
    listener, _ := net.Listen("tcp", ":1234")
    rpc.Accept(listener)
}

// 客户端
client, _ := rpc.Dial("tcp", "localhost:1234")
var reply int
args := &Args{A: 5, B: 6}
client.Call("Arith.Multiply", args, &reply)

2. gRPC (推荐)

gRPC是Google开发的跨语言RPC框架,支持多种语言。

// protobuf定义
syntax = "proto3";

service Calculator {
    rpc Multiply (MultiplyRequest) returns (MultiplyResponse);
}

message MultiplyRequest {
    int32 a = 1;
    int32 b = 2;
}

message MultiplyResponse {
    int32 result = 1;
}

// Go服务器端
type server struct{}

func (s *server) Multiply(ctx context.Context, req *pb.MultiplyRequest) (*pb.MultiplyResponse, error) {
    return &pb.MultiplyResponse{Result: req.A * req.B}, nil
}

func main() {
    lis, _ := net.Listen("tcp", ":50051")
    s := grpc.NewServer()
    pb.RegisterCalculatorServer(s, &server{})
    s.Serve(lis)
}

3. Hprose

支持多种语言的RPC框架,包括Go。

// 服务器端
package main

import (
    "github.com/hprose/hprose-golang/v3/rpc"
)

type Calculator struct {
    Multiply func(int, int) int `name:"multiply"`
}

func main() {
    service := rpc.NewService()
    calculator := new(Calculator)
    service.AddInstanceMethods(calculator)
    service.StartTCP("localhost:8412")
}

4. 对于Windows DLL的特殊考虑

关于你提到的Windows DLL加载限制,确实存在这个问题。Go 1.10+ 对Windows DLL导出有改进,但仍有限制。以下是一个导出函数的示例:

// export.go
package main

import "C"

//export Multiply
func Multiply(a, b int) int {
    return a * b
}

func main() {} // 必须的main函数

// 编译命令
// go build -buildmode=c-shared -o mylib.dll export.go

5. 替代方案:进程间通信(IPC)

考虑到Go DLL加载的限制,可以考虑使用进程间通信:

// Go服务进程
package main

import (
    "encoding/json"
    "net"
)

func handleConnection(conn net.Conn) {
    decoder := json.NewDecoder(conn)
    var req Request
    decoder.Decode(&req)
    
    result := req.A * req.B
    encoder := json.NewEncoder(conn)
    encoder.Encode(Response{Result: result})
    conn.Close()
}

func main() {
    ln, _ := net.Listen("tcp", ":8080")
    for {
        conn, _ := ln.Accept()
        go handleConnection(conn)
    }
}

对于你的具体需求(.NET宿主应用程序调用Go代码),建议采用以下方案:

  1. 使用gRPC进行跨语言通信
  2. 或者将Go代码编译为独立的服务进程,通过TCP/HTTP与.NET应用通信
  3. 如果必须使用DLL,确保只加载单个Go DLL,并通过C接口导出函数

这些方案都能实现远程且相对无缝的代码执行,具体选择取决于你的性能要求、部署复杂度和跨语言需求。

回到顶部