go语言自带的jsonrpc 不支持http/websocket,而是使用tcp协议,
所以我刚才在aardio中加了一个库 wsock.tcp.jsonClient 支持与go语言进行jsonrpc调用。
我们先调用go语言生成一个exe文件( 当然你可以把后缀名改为 dll,下面的代码一样可以运行 )
import golang;
var go = golang();//创建Go编译器
//Go源码与字符串都是UTF-8编码,跟aardio一样很方便
string.save("/gotest.go",`
package main
import (
"fmt"
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
)
type Args struct {
X, Y int
}
var listener net.Listener
type Calculator struct{}
func (t *Calculator) Add(args *Args, reply *int) error {
*reply = args.X + args.Y
return nil
}
func (t *Calculator) Exit(args *int, reply *int) error {
listener.Close()
return nil
}
func main() {
cal := new(Calculator)
server := rpc.NewServer()
server.Register(cal)
listener, e := net.Listen("tcp", "localhost:0")
if e != nil {
fmt.Printf("error:%s\n", e)
return
} else {
fmt.Printf("%s\n", listener.Addr().String())
}
for {
if conn, err := listener.Accept(); err != nil {
log.Fatal("error: " + err.Error())
} else {
go server.ServeCodec(jsonrpc.NewServerCodec(conn))
}
}
}`)
//编译Go源码生成EXE文件
go.build("/gotest.go");
console.pause();
假设上面用go语言生成的exe文件名为gotest.exe,并且是放在当前工程目录下,然后我们用下面的 aardio 代码调用这个 gotest.exe 里的go函数:
//RPC客户端 import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio调用go语言演示";right=759;bottom=469)
winform.add(
button={cls="button";text="调用Go语言的Calculator.Add函数";left=382;top=389;right=678;bottom=427;db=1;dr=1;z=5};
edit={cls="edit";left=19;top=12;right=732;bottom=352;db=1;dl=1;dr=1;dt=1;edge=1;hscroll=1;multiline=1;vscroll=1;z=1};
editX={cls="edit";text="2";left=109;top=392;right=185;bottom=424;db=1;dl=1;edge=1;z=2};
editY={cls="edit";text="3";left=238;top=392;right=320;bottom=420;db=1;dl=1;edge=1;z=3};
static={cls="static";text="+";left=198;top=395;right=230;bottom=420;align="center";db=1;dl=1;transparent=1;z=4}
)
/*}}*/
import wsock.tcp.jsonClient;
import process.popen;
/*
gotest.exe 是使用 go 语言编写的exe文件。
go 生成的 exe 可能在启动时误报病毒,选择信任即可。
*/
var goPrcs = process.popen("/gotest.exe");
goPrcs.codepage = 65001 //管道使用UTF8编码
if(!goPrcs) return winform.msgbox("启动go程序失败");
//读取服务端地址(使用自动分配的空闲端口避免冲突)
var url = goPrcs.read();
if( !url || string.startWith(url,"error:") ) return winform.msgbox("启动go程序失败");
//连接go语言服务端
var go = wsock.tcp.jsonClient(url)
winform.edit.print("已连接到go程序",url);
import process.job.limitKill;
goPrcs.assignToJobObject( process.job.limitKill );
winform.onDestroy = function(){
go.Calculator.Exit(0);//通知go程序退出
}
winform.button.oncommand = function(id,event){
//调用go语言提供的函数
var rep = go.Calculator.Add({
X = tonumber(winform.editX.text);
Y = tonumber(winform.editY.text);
} )
if( rep[["result"]] ){
winform.edit.print( "调用成功", rep.result )
}
else {
winform.edit.print( rep[["error"]] )
}
}
winform.show()
win.loopMessage();
|