Golang与Free Pascal的IPC或RPC实现探讨

Golang与Free Pascal的IPC或RPC实现探讨 我想在两个应用程序之间通过RPC或IPC进行双向通信……Golang和Free Pascal,反之亦然。

2 回复

你可以使用 gRPC(https://grpc.io/)

更多关于Golang与Free Pascal的IPC或RPC实现探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


对于在Go和Free Pascal之间实现IPC/RPC通信,最实用的方案是使用基于TCP的JSON-RPC。以下是具体实现示例:

Go服务端代码:

package main

import (
    "net"
    "net/rpc"
    "net/rpc/jsonrpc"
    "log"
)

type Args struct {
    A, B int
}

type Arith int

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, err := net.Listen("tcp", ":1234")
    if err != nil {
        log.Fatal("Listen error:", err)
    }
    
    for {
        conn, err := listener.Accept()
        if err != nil {
            continue
        }
        go jsonrpc.ServeConn(conn)
    }
}

Free Pascal客户端代码:

program PascalClient;

{$mode objfpc}{$H+}

uses
  SysUtils, fpjson, jsonparser, fpjsonrpc, ssockets;

type
  TJSONRPCClient = class
  private
    FSocket: TInetSocket;
  public
    constructor Create(Host: string; Port: Integer);
    destructor Destroy; override;
    function CallMethod(const Method: string; Params: TJSONArray): TJSONData;
  end;

constructor TJSONRPCClient.Create(Host: string; Port: Integer);
begin
  FSocket := TInetSocket.Create(Host, Port);
end;

destructor TJSONRPCClient.Destroy;
begin
  FSocket.Free;
  inherited;
end;

function TJSONRPCClient.CallMethod(const Method: string; Params: TJSONArray): TJSONData;
var
  Request, Response: TJSONObject;
  Stream: TStringStream;
begin
  Request := TJSONObject.Create;
  try
    Request.Add('jsonrpc', '2.0');
    Request.Add('method', Method);
    Request.Add('params', Params);
    Request.Add('id', 1);
    
    Stream := TStringStream.Create(Request.AsJSON);
    try
      FSocket.Write(Stream.DataString[1], Length(Stream.DataString));
      
      SetLength(ResponseStr, 4096);
      BytesRead := FSocket.Read(ResponseStr[1], Length(ResponseStr));
      SetLength(ResponseStr, BytesRead);
      
      Response := TJSONObject(GetJSON(ResponseStr));
      Result := Response.Get('result', TJSONData(nil));
    finally
      Stream.Free;
    end;
  finally
    Request.Free;
  end;
end;

var
  Client: TJSONRPCClient;
  Params: TJSONArray;
  Result: TJSONData;
begin
  Client := TJSONRPCClient.Create('localhost', 1234);
  try
    Params := TJSONArray.Create;
    Params.Add(5);
    Params.Add(6);
    
    Result := Client.CallMethod('Arith.Multiply', Params);
    if Assigned(Result) then
      WriteLn('Result: ', Result.AsInteger);
  finally
    Client.Free;
  end;
end.

Go客户端调用Free Pascal服务端:

package main

import (
    "net/rpc/jsonrpc"
    "log"
    "fmt"
)

func main() {
    client, err := jsonrpc.Dial("tcp", "localhost:1235")
    if err != nil {
        log.Fatal("Dial error:", err)
    }
    defer client.Close()
    
    args := &Args{7, 8}
    var reply int
    
    err = client.Call("Arith.Multiply", args, &reply)
    if err != nil {
        log.Fatal("Call error:", err)
    }
    
    fmt.Printf("Result: %d\n", reply)
}

Free Pascal服务端代码:

program PascalServer;

{$mode objfpc}{$H+}

uses
  SysUtils, fpjson, jsonparser, fpjsonrpc, ssockets, classes;

type
  TArithHandler = class
    class procedure Multiply(const Params: TJSONData; out Result: TJSONData);
  end;

class procedure TArithHandler.Multiply(const Params: TJSONData; out Result: TJSONData);
var
  A, B: Integer;
begin
  A := Params.Items[0].AsInteger;
  B := Params.Items[1].AsInteger;
  Result := TJSONIntegerNumber.Create(A * B);
end;

var
  Server: TJSONRPCServerHandler;
  Socket: TInetSocket;
  ClientSocket: TInetSocket;
begin
  Server := TJSONRPCServerHandler.Create;
  Server.RegisterMethod('Arith.Multiply', @TArithHandler.Multiply);
  
  Socket := TInetSocket.Create(1235);
  try
    while True do
    begin
      ClientSocket := Socket.Accept;
      try
        Server.HandleRequest(ClientSocket);
      finally
        ClientSocket.Free;
      end;
    end;
  finally
    Socket.Free;
  end;
end.

这个方案使用JSON-RPC over TCP,具有以下优势:

  1. 跨语言兼容性好,JSON是通用数据格式
  2. TCP提供可靠的连接和双向通信能力
  3. 实现简单,双方都有成熟的JSON-RPC库支持
  4. 支持异步通信和并发处理

对于需要更高性能的场景,可以考虑使用Protocol Buffers(protobuf)替代JSON,但需要双方都实现protobuf的编解码。

回到顶部