1 Star 0 Fork 0

larry_dev/gtpengine

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
connection.go 3.03 KB
一键复制 编辑 原始数据 按行查看 历史
larry_dev 提交于 2019-07-10 17:15 . 修改
package gtpengine
import (
"bufio"
"errors"
"fmt"
"io"
"log"
"os/exec"
"strings"
)
type GTPConnection struct {
cmd *exec.Cmd
infile io.WriteCloser
outfile io.ReadCloser
errfile io.ReadCloser
ShowLog bool
wait chan int
}
// NewGTPConnection 创建GTP连接器
func NewGTPConnection(cmd string, args ...string) (*GTPConnection, error) {
conn := GTPConnection{ShowLog: false, wait: make(chan int, 1)}
conn.cmd = exec.Command(cmd, args...)
inf, err := conn.cmd.StdinPipe() //获取输入管道,后续通过管道与AI进行交互
if err != nil {
return nil, err
}
conn.infile = inf
outf, err := conn.cmd.StdoutPipe() //获取输入管道,在输入管道有命令进入时,通过输出管道获取命令返回值
if err != nil {
return nil, err
}
conn.outfile = outf
errf, err := conn.cmd.StderrPipe() //获取输入管道,在输入管道有命令进入时,通过输出管道获取命令返回值
if err != nil {
return nil, err
}
conn.errfile = errf
conn.cmd.Start() //开始命令,并且程序继续执行
//异步等待,不阻塞程序执行
go func() {
conn.cmd.Wait()
}()
return &conn, nil
}
// 完整PATH,自动解析为对应命令行
func NewGTPConnectionByPath(path string) (*GTPConnection, error) {
s1 := strings.Fields(path)
command := s1[0]
return NewGTPConnection(command, s1[1:]...)
}
func (g *GTPConnection) SettingLog(w io.Writer) {
g.ShowLog = true
//g.logger = log.New(w, "", 0)
}
func (g *GTPConnection) WriteLog(info ...interface{}) {
if g.ShowLog {
log.Println(info)
}
}
// Exec 通过管道执行命令并得到返回值
func (g *GTPConnection) Exec(cmd string) (string, error) {
//通过输入管道执行命令
g.WriteLog(fmt.Sprintf("input>> %s", cmd))
g.infile.Write([]byte(fmt.Sprintf("%s\n", cmd)))
//读取输出管道的值,因为输出管道是一个io.ReadCloser,所以我们可以通过bufio.NewReader()来读取返回值
reader := bufio.NewReader(g.outfile)
result := ""
for {
line, err := reader.ReadString('\n')
if err != nil || io.EOF == err {
break
}
if (strings.Contains(result, "=") || strings.Contains(result, "?")) && (line == "\n" || line == "\r\n") {
break
}
if line != "\n" && line != "\r\n" {
result += line
}
}
g.WriteLog(fmt.Sprintf("output>> %s", result))
res := strings.Split(result, "")
l := len(res)
if l > 0 {
if res[l-1] == "\n" {
result = strings.Join(res[:l-1], "")
}
if len(result) == 0 {
return "", errors.New("ERROR length=0")
}
if res[0] == "=" {
return strings.TrimSpace(strings.Join(res[2:], "")), nil
}
if res[0] == "?" {
return "", errors.New(strings.Join(res[2:], ""))
}
}
return "", errors.New("ERROR: Unrecognized answer: " + result)
}
func (g *GTPConnection) ListenInfo(cb func(i string)) {
reader := bufio.NewReader(g.errfile)
for {
select {
case <-g.wait:
g.WriteLog("关闭")
return
default:
line, _ := reader.ReadString('\n')
cb(line)
}
}
}
// Close 释放GTP资源
func (g GTPConnection) Close() {
g.infile.Close()
g.outfile.Close()
g.errfile.Close()
g.wait <- 1
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/larry_dev/gtpengine.git
git@gitee.com:larry_dev/gtpengine.git
larry_dev
gtpengine
gtpengine
master

搜索帮助