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,具有以下优势:
- 跨语言兼容性好,JSON是通用数据格式
- TCP提供可靠的连接和双向通信能力
- 实现简单,双方都有成熟的JSON-RPC库支持
- 支持异步通信和并发处理
对于需要更高性能的场景,可以考虑使用Protocol Buffers(protobuf)替代JSON,但需要双方都实现protobuf的编解码。

