forked from x/ContextOS
Merge branch '0.2.0'
This commit is contained in:
commit
0a84f833aa
12
etc/init.sh
12
etc/init.sh
@ -0,0 +1,12 @@
|
|||||||
|
# @debug on
|
||||||
|
~aaa
|
||||||
|
# login root 94ca7394d007fa189cc4be0a2625d716 root
|
||||||
|
login root root
|
||||||
|
|
||||||
|
~cli
|
||||||
|
remote slaver listen :9393 tcp
|
||||||
|
|
||||||
|
# ~aaa
|
||||||
|
# login shy shy
|
||||||
|
userinfo add context hi hello nice
|
||||||
|
userinfo add command hi context
|
@ -5,6 +5,7 @@ import ( // {{{
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -20,11 +21,13 @@ type CLI struct {
|
|||||||
ins []io.ReadCloser
|
ins []io.ReadCloser
|
||||||
bio *bufio.Reader
|
bio *bufio.Reader
|
||||||
bios []*bufio.Reader
|
bios []*bufio.Reader
|
||||||
|
bufs [][]byte
|
||||||
|
|
||||||
history []map[string]string
|
history []map[string]string
|
||||||
alias map[string]string
|
alias map[string]string
|
||||||
next string
|
next string
|
||||||
exit bool
|
exit bool
|
||||||
|
login *ctx.Context
|
||||||
|
|
||||||
target *ctx.Context
|
target *ctx.Context
|
||||||
*ctx.Context
|
*ctx.Context
|
||||||
@ -44,8 +47,33 @@ func (cli *CLI) push(f io.ReadCloser) { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (cli *CLI) parse(m *ctx.Message) bool { // {{{
|
func (cli *CLI) parse(m *ctx.Message) bool { // {{{
|
||||||
if len(cli.ins) == 1 || cli.Conf("slient") != "yes" {
|
if len(cli.ins) == 1 && cli.Owner == nil {
|
||||||
cli.echo(cli.Conf("PS1"))
|
if aaa := cli.Root.Find("aaa"); aaa != nil {
|
||||||
|
|
||||||
|
username := ""
|
||||||
|
fmt.Fprintf(cli.out, "username>")
|
||||||
|
fmt.Fscanln(cli.in, &username)
|
||||||
|
|
||||||
|
password := ""
|
||||||
|
fmt.Fprintf(cli.out, "password>")
|
||||||
|
fmt.Fscanln(cli.in, &password)
|
||||||
|
|
||||||
|
msg := m.Spawn(aaa, "username")
|
||||||
|
|
||||||
|
if msg.Cmd("login", username, password) == "" {
|
||||||
|
fmt.Fprintln(cli.out, "登录失败")
|
||||||
|
m.Cmd("exit")
|
||||||
|
cli.out.Close()
|
||||||
|
cli.in.Close()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Cap("username", msg.Cap("username"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cli.ins) == 1 || m.Conf("slient") != "yes" {
|
||||||
|
cli.echo(m.Conf("PS1"))
|
||||||
}
|
}
|
||||||
|
|
||||||
line := ""
|
line := ""
|
||||||
@ -53,23 +81,20 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{
|
|||||||
ls, e := cli.bio.ReadString('\n')
|
ls, e := cli.bio.ReadString('\n')
|
||||||
if e == io.EOF {
|
if e == io.EOF {
|
||||||
l := len(cli.ins)
|
l := len(cli.ins)
|
||||||
if l == 1 {
|
if l > 1 {
|
||||||
// cli.echo("\n%s\n", cli.Conf("结束语"))
|
|
||||||
return false
|
|
||||||
ls = "exit"
|
|
||||||
e = nil
|
|
||||||
} else {
|
|
||||||
cli.ins = cli.ins[:l-1]
|
cli.ins = cli.ins[:l-1]
|
||||||
cli.bios = cli.bios[:l-1]
|
cli.bios = cli.bios[:l-1]
|
||||||
cli.in = cli.ins[l-2]
|
cli.in = cli.ins[l-2]
|
||||||
cli.bio = cli.bios[l-2]
|
cli.bio = cli.bios[l-2]
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// cli.echo("\n%s\n", cli.Conf("结束语"))
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
cli.Assert(e)
|
m.Assert(e)
|
||||||
line = ls
|
line = ls
|
||||||
|
|
||||||
if len(cli.ins) > 1 || cli.Conf("slient") != "yes" {
|
if len(cli.ins) > 1 && m.Conf("slient") != "yes" {
|
||||||
cli.echo(line)
|
cli.echo(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +109,7 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{
|
|||||||
line = cli.next
|
line = cli.next
|
||||||
cli.next = ""
|
cli.next = ""
|
||||||
|
|
||||||
if cli.Conf("slient") != "yes" {
|
if m.Conf("slient") != "yes" {
|
||||||
cli.echo(line)
|
cli.echo(line)
|
||||||
cli.echo("\n")
|
cli.echo("\n")
|
||||||
}
|
}
|
||||||
@ -145,14 +170,44 @@ back:
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (cli *CLI) echo(str string, arg ...interface{}) { // {{{
|
func (cli *CLI) echo(str string, arg ...interface{}) { // {{{
|
||||||
if len(cli.ins) == 1 || cli.Conf("slient") != "yes" {
|
// if len(cli.ins) == 1 || m.Conf("slient") != "yes" {
|
||||||
fmt.Fprintf(cli.out, str, arg...)
|
fmt.Fprintf(cli.out, str, arg...)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||||
|
cli.Caches["username"] = &ctx.Cache{Name: "登录用户", Value: "", Help: "登录用户名"}
|
||||||
|
cli.Caches["nhistory"] = &ctx.Cache{Name: "历史命令数量", Value: "0", Help: "当前终端已经执行命令的数量", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string {
|
||||||
|
x.Value = fmt.Sprintf("%d", len(cli.history))
|
||||||
|
return x.Value
|
||||||
|
}}
|
||||||
|
|
||||||
|
cli.Configs["slient"] = &ctx.Config{Name: "屏蔽脚本输出(yes/no)", Value: "yes", Help: "屏蔽脚本输出的信息,yes:屏蔽,no:不屏蔽"}
|
||||||
|
cli.Configs["default"] = &ctx.Config{Name: "默认的搜索起点(root/back/home)", Value: "root", Help: "模块搜索的默认起点,root:从根模块,back:从父模块,home:从当前模块"}
|
||||||
|
cli.Configs["PS1"] = &ctx.Config{Name: "命令行提示符(target/detail)", Value: "target", Help: "命令行提示符,target:显示当前模块,detail:显示详细信息", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
||||||
|
cli, ok := m.Target.Server.(*CLI) // {{{
|
||||||
|
if ok && cli.target != nil {
|
||||||
|
// c = cli.target
|
||||||
|
switch x.Value {
|
||||||
|
case "target":
|
||||||
|
return fmt.Sprintf("%s[%s]\033[32m%s\033[0m> ", m.Cap("nhistory"), time.Now().Format("15:04:05"), cli.target.Name)
|
||||||
|
case "detail":
|
||||||
|
return fmt.Sprintf("%s[%s](%s,%s,%s)\033[32m%s\033[0m> ", m.Cap("nhistory"), time.Now().Format("15:04:05"), m.Cap("ncontext"), m.Cap("nmessage"), m.Cap("nserver"), m.Target.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("[%s]\033[32m%s\033[0m ", time.Now().Format("15:04:05"), x.Value)
|
||||||
|
// }}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
if len(arg) > 0 {
|
||||||
|
cli.Configs["init.sh"] = &ctx.Config{Name: "启动脚本", Value: arg[0], Help: "模块启动时自动运行的脚本"}
|
||||||
|
}
|
||||||
|
|
||||||
|
cli.target = cli.Context
|
||||||
cli.history = make([]map[string]string, 0, 100)
|
cli.history = make([]map[string]string, 0, 100)
|
||||||
cli.alias = map[string]string{
|
cli.alias = map[string]string{
|
||||||
"~": "context",
|
"~": "context",
|
||||||
@ -161,48 +216,50 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
"$": "cache",
|
"$": "cache",
|
||||||
"&": "server",
|
"&": "server",
|
||||||
"*": "message",
|
"*": "message",
|
||||||
|
":": "command",
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.target = cli.Context
|
|
||||||
|
|
||||||
cli.Caches["nhistory"] = &ctx.Cache{Name: "历史命令数量", Value: "0", Help: "当前终端已经执行命令的数量", Hand: func(c *ctx.Context, x *ctx.Cache, arg ...string) string {
|
|
||||||
x.Value = fmt.Sprintf("%d", len(cli.history))
|
|
||||||
return x.Value
|
|
||||||
}}
|
|
||||||
|
|
||||||
return cli
|
return cli
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
cli.Capi("nterm", 1)
|
m.Capi("nterm", 1)
|
||||||
defer cli.Capi("nterm", -1)
|
defer m.Capi("nterm", -1)
|
||||||
|
|
||||||
if cli.Messages == nil {
|
|
||||||
cli.Messages = make(chan *ctx.Message, cli.Confi("MessageQueueSize"))
|
|
||||||
}
|
|
||||||
if len(arg) > 0 {
|
|
||||||
cli.Conf("init.sh", "启动脚本", arg[0], "模块启动时自动运行的脚本")
|
|
||||||
}
|
|
||||||
|
|
||||||
if stream, ok := m.Data["io"]; ok {
|
if stream, ok := m.Data["io"]; ok {
|
||||||
io := stream.(io.ReadWriteCloser)
|
io := stream.(io.ReadWriteCloser)
|
||||||
cli.out = io
|
cli.out = io
|
||||||
cli.push(io)
|
cli.push(io)
|
||||||
|
|
||||||
if f, e := os.Open(cli.Conf("init.sh")); e == nil {
|
if m.Has("master") {
|
||||||
cli.push(f)
|
log.Println(cli.Name, "master terminal:")
|
||||||
}
|
if cli.bufs == nil {
|
||||||
|
cli.bufs = make([][]byte, 0, 10)
|
||||||
// cli.echo("%s\n", cli.Conf("hello"))
|
|
||||||
|
|
||||||
go cli.AssertOne(m, true, func(c *ctx.Context, m *ctx.Message) {
|
|
||||||
for cli.parse(m) {
|
|
||||||
}
|
}
|
||||||
})
|
for {
|
||||||
|
b := make([]byte, 128)
|
||||||
|
n, e := cli.bio.Read(b)
|
||||||
|
log.Println(cli.Name, "read:", n)
|
||||||
|
m.Assert(e)
|
||||||
|
cli.bufs = append(cli.bufs, b)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
log.Println(cli.Name, "slaver terminal:")
|
||||||
|
|
||||||
|
if f, e := os.Open(m.Conf("init.sh")); e == nil {
|
||||||
|
cli.push(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
go m.AssertOne(m, true, func(m *ctx.Message) {
|
||||||
|
for cli.parse(m) {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for cli.Deal(func(msg *ctx.Message, arg ...string) bool {
|
for m.Deal(func(msg *ctx.Message, arg ...string) bool {
|
||||||
if a, ok := cli.alias[arg[0]]; ok {
|
if a, ok := cli.alias[arg[0]]; ok {
|
||||||
arg[0] = a
|
arg[0] = a
|
||||||
}
|
}
|
||||||
@ -235,6 +292,7 @@ func (cli *CLI) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server
|
|||||||
c.Caches = map[string]*ctx.Cache{}
|
c.Caches = map[string]*ctx.Cache{}
|
||||||
c.Configs = map[string]*ctx.Config{}
|
c.Configs = map[string]*ctx.Config{}
|
||||||
|
|
||||||
|
c.Owner = nil
|
||||||
s := new(CLI)
|
s := new(CLI)
|
||||||
s.Context = c
|
s.Context = c
|
||||||
return s
|
return s
|
||||||
@ -242,9 +300,14 @@ func (cli *CLI) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (cli *CLI) Exit(m *ctx.Message, arg ...string) bool { // {{{
|
func (cli *CLI) Exit(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
if cli.Context != Index {
|
switch cli.Context {
|
||||||
delete(cli.Context.Context.Contexts, cli.Name)
|
case m.Source:
|
||||||
|
return false
|
||||||
|
|
||||||
|
case m.Target:
|
||||||
|
log.Println(cli.Name, "release:")
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,159 +317,105 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
Caches: map[string]*ctx.Cache{
|
Caches: map[string]*ctx.Cache{
|
||||||
"nterm": &ctx.Cache{Name: "终端数量", Value: "0", Help: "已经运行的终端数量"},
|
"nterm": &ctx.Cache{Name: "终端数量", Value: "0", Help: "已经运行的终端数量"},
|
||||||
},
|
},
|
||||||
Configs: map[string]*ctx.Config{
|
Configs: map[string]*ctx.Config{},
|
||||||
"slient": &ctx.Config{Name: "屏蔽脚本输出(yes/no)", Value: "yes", Help: "屏蔽脚本输出的信息,yes:屏蔽,no:不屏蔽"},
|
|
||||||
// "hello": &ctx.Config{Name: "开场白", Value: "\n~~~ Hello Context & Message World ~~~\n", Help: "模块启动时输出的信息"},
|
|
||||||
// "byebye": &ctx.Config{Name: "结束语", Value: "\n~~~ Byebye Context & Message World ~~~\n", Help: "模块停止时输出的信息"},
|
|
||||||
|
|
||||||
"PS1": &ctx.Config{Name: "命令行提示符(target/detail)", Value: "target", Help: "命令行提示符,target:显示当前模块,detail:显示详细信息", Hand: func(c *ctx.Context, x *ctx.Config, arg ...string) string {
|
|
||||||
cli, ok := c.Server.(*CLI) // {{{
|
|
||||||
if ok && cli.target != nil {
|
|
||||||
// c = cli.target
|
|
||||||
switch x.Value {
|
|
||||||
case "target":
|
|
||||||
return fmt.Sprintf("%s[%s]\033[32m%s\033[0m> ", c.Cap("nhistory"), time.Now().Format("15:04:05"), cli.target.Name)
|
|
||||||
case "detail":
|
|
||||||
return fmt.Sprintf("%s[%s](%s,%s,%s)\033[32m%s\033[0m> ", c.Cap("nhistory"), time.Now().Format("15:04:05"), c.Cap("ncontext"), c.Cap("nmessage"), c.Cap("nserver"), c.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("[%s]\033[32m%s\033[0m ", time.Now().Format("15:04:05"), x.Value)
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
"context": &ctx.Command{Name: "context [root|back|home] [[find|search] name] [show|spawn|start|switch][args]", Help: "查找并操作模块,\n查找起点root:根模块、back:父模块、home:本模块,\n查找方法find:路径匹配、search:模糊匹配,\n查找对象name:支持点分和正则,\n操作类型show:显示信息、switch:切换为当前、start:启动模块、spawn:分裂子模块,args:启动参数", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"context": &ctx.Command{Name: "context [root|back|home] [[find|search] name] [show|spawn|start|switch][args]", Help: "查找并操作模块,\n查找起点root:根模块、back:父模块、home:本模块,\n查找方法find:路径匹配、search:模糊匹配,\n查找对象name:支持点分和正则,\n操作类型show:显示信息、switch:切换为当前、start:启动模块、spawn:分裂子模块,args:启动参数",
|
||||||
cli, ok := c.Server.(*CLI) // {{{
|
Formats: map[string]int{"root": 0, "back": 0, "home": 0, "find": 1, "search": 1, "show": 0, "switch": 0, "start": -1, "spawn": -1},
|
||||||
if !ok {
|
Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
return ""
|
cli, ok := m.Source.Server.(*CLI) // {{{
|
||||||
}
|
if !ok {
|
||||||
|
cli, ok = c.Server.(*CLI)
|
||||||
switch len(arg) {
|
if !ok {
|
||||||
case 0:
|
return ""
|
||||||
m.Target.Root.Travel(func(c *ctx.Context) bool {
|
|
||||||
if c.Context != nil {
|
|
||||||
m.Echo("%s: %s(%s)\n", c.Context.Name, c.Name, c.Help)
|
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
})
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
target := m.Target
|
|
||||||
method := "search"
|
|
||||||
action := "switch"
|
|
||||||
which := ""
|
|
||||||
args := []string{}
|
|
||||||
|
|
||||||
for len(arg) > 0 {
|
|
||||||
switch arg[0] {
|
|
||||||
case "root":
|
|
||||||
target = m.Target.Root
|
|
||||||
case "back":
|
|
||||||
if m.Target.Context != nil {
|
|
||||||
target = m.Target.Context
|
|
||||||
}
|
|
||||||
case "home":
|
|
||||||
target = m.Target
|
|
||||||
case "find", "search":
|
|
||||||
method = arg[0]
|
|
||||||
which = arg[1]
|
|
||||||
arg = arg[1:]
|
|
||||||
case "switch", "spawn", "start", "show":
|
|
||||||
action = arg[0]
|
|
||||||
args = arg[1:]
|
|
||||||
arg = arg[:1]
|
|
||||||
default:
|
|
||||||
which = arg[0]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = arg[1:]
|
switch len(arg) {
|
||||||
}
|
case 0:
|
||||||
|
m.Travel(m.Target.Root, func(m *ctx.Message) bool {
|
||||||
|
if m.Target.Context != nil {
|
||||||
|
target := m.Target
|
||||||
|
m.Target = m.Target.Owner
|
||||||
|
if m.Target != nil && m.Check(m.Target, "caches", "username") && m.Check(m.Target, "caches", "group") {
|
||||||
|
m.Echo("%s: %s(%s) %s %s\n", target.Context.Name, target.Name, target.Help, m.Cap("username"), m.Cap("group"))
|
||||||
|
} else {
|
||||||
|
m.Echo("%s: %s(%s)\n", target.Context.Name, target.Name, target.Help)
|
||||||
|
}
|
||||||
|
m.Target = target
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
cs := []*ctx.Context{}
|
target := m.Target.Root
|
||||||
|
if m.Has("home") {
|
||||||
|
target = m.Target
|
||||||
|
}
|
||||||
|
if m.Has("root") {
|
||||||
|
target = m.Target.Root
|
||||||
|
}
|
||||||
|
if m.Has("back") && target.Context != nil {
|
||||||
|
target = m.Target.Context
|
||||||
|
}
|
||||||
|
|
||||||
if which == "" {
|
cs := []*ctx.Context{}
|
||||||
cs = append(cs, target)
|
switch {
|
||||||
} else {
|
case m.Has("search"):
|
||||||
switch method {
|
if s := m.Search(target, m.Get("search")); len(s) > 0 {
|
||||||
case "search":
|
|
||||||
if s := target.Search(which); len(s) > 0 {
|
|
||||||
cs = append(cs, s...)
|
cs = append(cs, s...)
|
||||||
}
|
}
|
||||||
case "find":
|
case m.Has("find"):
|
||||||
if s := target.Find(which); s != nil {
|
if s := target.Find(m.Get("find")); s != nil {
|
||||||
cs = append(cs, s)
|
cs = append(cs, s)
|
||||||
}
|
}
|
||||||
}
|
case m.Has("args"):
|
||||||
}
|
if s := m.Search(target, m.Get("args")); len(s) > 0 {
|
||||||
|
cs = append(cs, s...)
|
||||||
for _, v := range cs {
|
|
||||||
switch action {
|
|
||||||
case "switch":
|
|
||||||
cli.target = v
|
|
||||||
case "spawn":
|
|
||||||
msg := m.Spawn(v)
|
|
||||||
// msg.Add("detail", args[1:]...)
|
|
||||||
v.Spawn(msg, args[0]).Begin(msg)
|
|
||||||
case "start":
|
|
||||||
m.Message.Spawn(v, args[0]).Start(arg[0], args[1:]...)
|
|
||||||
case "show":
|
|
||||||
m.Echo("%s: %s\n", v.Name, v.Help)
|
|
||||||
m.Echo("引用模块:\n")
|
|
||||||
for k, v := range v.Sessions {
|
|
||||||
m.Echo("\t%s(%d): %s %s\n", k, v.Code, v.Target.Name, v.Target.Help)
|
|
||||||
}
|
}
|
||||||
m.Echo("索引模块:\n")
|
default:
|
||||||
for i, v := range v.Requests {
|
cs = append(cs, target)
|
||||||
m.Echo("\t%d(%d): %s %s\n", i, v.Code, v.Context.Name, v.Context.Help)
|
}
|
||||||
|
|
||||||
|
for _, v := range cs {
|
||||||
|
// if !m.Source.Check(v) {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
switch {
|
||||||
|
case m.Has("start"):
|
||||||
|
args := m.Meta["start"]
|
||||||
|
m.Message.Spawn(v, args[0]).Start(arg[0], args[1:]...)
|
||||||
|
case m.Has("spawn"):
|
||||||
|
args := m.Meta["spawn"]
|
||||||
|
msg := m.Spawn(v)
|
||||||
|
v.Spawn(msg, args[0]).Begin(msg)
|
||||||
|
case m.Has("switch"):
|
||||||
|
cli.target = v
|
||||||
|
case m.Has("show"):
|
||||||
|
m.Echo("%s: %s\n", v.Name, v.Help)
|
||||||
|
m.Echo("模块资源:\n")
|
||||||
|
for i, v := range v.Requests {
|
||||||
|
m.Echo("\t%d(%d): <- %s %s\n", i, v.Code, v.Source.Name, v.Source.Help)
|
||||||
|
}
|
||||||
|
m.Echo("模块引用:\n")
|
||||||
|
for k, v := range v.Sessions {
|
||||||
|
m.Echo("\t%s(%d): -> %s %s\n", k, v.Code, v.Target.Name, v.Target.Help)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cli.target = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"message": &ctx.Command{Name: "message", Help: "查看上下文", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
ms := []*ctx.Message{ctx.Pulse} // {{{
|
|
||||||
for i := 0; i < len(ms); i++ {
|
|
||||||
m.Echo("%d %s.%s -> %s.%d: %s %v\n", ms[i].Code, ms[i].Context.Name, ms[i].Name, ms[i].Target.Name, ms[i].Index, ms[i].Time.Format("15:04:05"), ms[i].Meta["detail"])
|
|
||||||
ms = append(ms, ms[i].Messages...)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"server": &ctx.Command{Name: "server start|stop|switch", Help: "服务启动停止切换", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
s := m.Target // {{{
|
|
||||||
switch len(arg) {
|
|
||||||
case 0:
|
|
||||||
m.Target.Root.Travel(func(c *ctx.Context) bool {
|
|
||||||
if x, ok := c.Caches["status"]; ok {
|
|
||||||
m.Echo("%s(%s): %s\n", c.Name, x.Value, c.Help)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
switch arg[0] {
|
|
||||||
case "start":
|
|
||||||
if s != nil {
|
|
||||||
go s.Start(m)
|
|
||||||
}
|
|
||||||
case "stop":
|
|
||||||
case "switch":
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"source": &ctx.Command{Name: "source file", Help: "运行脚本", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"source": &ctx.Command{Name: "source file", Help: "运行脚本", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
cli := c.Server.(*CLI) // {{{
|
cli := c.Server.(*CLI) // {{{
|
||||||
switch len(arg) {
|
switch len(arg) {
|
||||||
case 1:
|
case 1:
|
||||||
f, e := os.Open(arg[0])
|
f, e := os.Open(arg[0])
|
||||||
c.Assert(e)
|
m.Assert(e)
|
||||||
cli.push(f)
|
cli.push(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,166 +465,56 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"command": &ctx.Command{Name: "command [all] [name args]", Help: "查看修改添加配置", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"remote": &ctx.Command{Name: "remote [send args...]|[[master|slaver] listen|dial address protocol]", Help: "建立远程连接",
|
||||||
all := false // {{{
|
Formats: map[string]int{"send": -1, "master": 0, "slaver": 0, "listen": 1, "dial": 1},
|
||||||
if len(arg) > 0 && arg[0] == "all" {
|
Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
arg = arg[1:]
|
if m.Has("send") { // {{{
|
||||||
all = true
|
cli := m.Target.Server.(*CLI)
|
||||||
}
|
|
||||||
|
|
||||||
m.Target.BackTrace(func(s *ctx.Context) bool {
|
cli.out.Write([]byte(strings.Join(m.Meta["args"], " ") + "\n"))
|
||||||
switch len(arg) {
|
m.Echo("~~~remote~~~\n")
|
||||||
case 0:
|
time.Sleep(100 * time.Millisecond)
|
||||||
for k, v := range s.Commands {
|
for _, b := range cli.bufs {
|
||||||
m.Echo("%s: %s\n", k, v.Name)
|
m.Echo("%s", string(b))
|
||||||
}
|
}
|
||||||
case 1:
|
cli.bufs = cli.bufs[0:0]
|
||||||
if v, ok := s.Commands[arg[0]]; ok {
|
m.Echo("\n~~~remote~~~\n")
|
||||||
m.Echo("%s\n%s\n", v.Name, v.Help)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
m.Spawn(s).Cmd(arg...)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return all
|
|
||||||
})
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"config": &ctx.Command{Name: "config [all] [key value|[name value help]]", Help: "查看修改添加配置", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
all := false // {{{
|
|
||||||
if len(arg) > 0 && arg[0] == "all" {
|
|
||||||
arg = arg[1:]
|
|
||||||
all = true
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Target.BackTrace(func(s *ctx.Context) bool {
|
return ""
|
||||||
switch len(arg) {
|
|
||||||
case 0:
|
|
||||||
for k, v := range s.Configs {
|
|
||||||
m.Echo("%s(%s): %s\n", k, v.Value, v.Name)
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
if v, ok := s.Configs[arg[0]]; ok {
|
|
||||||
m.Echo("%s: %s\n", v.Name, v.Help)
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
if s != m.Target {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch arg[0] {
|
|
||||||
case "void":
|
|
||||||
s.Conf(arg[1], "")
|
|
||||||
case "delete":
|
|
||||||
if _, ok := s.Configs[arg[1]]; ok {
|
|
||||||
delete(s.Configs, arg[1])
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
s.Conf(arg[0], arg[1])
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
s.Conf(arg[0], arg[1:]...)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return all
|
|
||||||
})
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"cache": &ctx.Command{Name: "cache [all] [key value|[name value help]]", Help: "查看修改添加配置", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
all := false // {{{
|
|
||||||
if len(arg) > 0 && arg[0] == "all" {
|
|
||||||
arg = arg[1:]
|
|
||||||
all = true
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Target.BackTrace(func(s *ctx.Context) bool {
|
|
||||||
switch len(arg) {
|
|
||||||
case 0:
|
|
||||||
for k, v := range s.Caches {
|
|
||||||
m.Echo("%s(%s): %s\n", k, v.Value, v.Name)
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
if v, ok := s.Caches[arg[0]]; ok {
|
|
||||||
m.Echo("%s: %s\n", v.Name, v.Help)
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
if s != m.Target {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch arg[0] {
|
|
||||||
case "delete":
|
|
||||||
if _, ok := s.Caches[arg[1]]; ok {
|
|
||||||
delete(s.Caches, arg[1])
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if _, ok := s.Caches[arg[0]]; ok {
|
|
||||||
m.Echo("%s: %s\n", arg[0], s.Cap(arg[0], arg[1:]...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
s.Cap(arg[0], arg[1:]...)
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return all
|
s := c.Root.Find(m.Get("args"))
|
||||||
})
|
action := "dial"
|
||||||
return ""
|
if m.Has("listen") {
|
||||||
// }}}
|
action = "listen"
|
||||||
}},
|
|
||||||
"exit": &ctx.Command{Name: "exit", Help: "退出", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
cli, ok := m.Target.Server.(*CLI) // {{{
|
|
||||||
if !ok {
|
|
||||||
cli, ok = m.Context.Server.(*CLI)
|
|
||||||
}
|
|
||||||
if ok {
|
|
||||||
if !cli.exit {
|
|
||||||
m.Echo(c.Conf("结束语"))
|
|
||||||
cli.Context.Exit(m)
|
|
||||||
}
|
}
|
||||||
cli.exit = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
msg := m.Spawn(s)
|
||||||
// }}}
|
if m.Has("master") {
|
||||||
}},
|
msg.Template = msg.Spawn(msg.Source).Add("option", "master")
|
||||||
"remote": &ctx.Command{Name: "remote master|slave listen|dial address protocol", Help: "建立远程连接", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
switch len(arg) { // {{{
|
|
||||||
case 0:
|
|
||||||
case 4:
|
|
||||||
if arg[0] == "master" {
|
|
||||||
if arg[1] == "dial" {
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if arg[1] == "listen" {
|
|
||||||
s := c.Root.Find(arg[3])
|
|
||||||
m.Message.Spawn(s, arg[2]).Cmd("listen", arg[2])
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"open": &ctx.Command{Name: "open address protocl", Help: "建立远程连接",
|
|
||||||
Options: map[string]string{"io": "读写流"},
|
|
||||||
Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { // {{{
|
|
||||||
if m.Has("io") {
|
|
||||||
m.Start(fmt.Sprintf("PTS%d", c.Capi("nterm")), arg[1])
|
|
||||||
} else {
|
|
||||||
switch arg[1] {
|
|
||||||
case "tcp":
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
msg.Cmd(action, m.Get(action))
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}},
|
||||||
|
// }}}
|
||||||
|
"open": &ctx.Command{Name: "open [master|slaver] [script [log]]", Help: "建立远程连接",
|
||||||
|
Options: map[string]string{"master": "主控终端", "slaver": "被控终端", "args": "启动参数", "io": "读写流"},
|
||||||
|
Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
|
go m.Start(fmt.Sprintf("PTS%d", m.Capi("nterm")), m.Meta["args"]...) // {{{
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"void": &ctx.Command{Name: "", Help: "", Hand: nil},
|
"void": &ctx.Command{Name: "", Help: "", Hand: nil},
|
||||||
},
|
},
|
||||||
Messages: make(chan *ctx.Message, 10),
|
Messages: make(chan *ctx.Message, 10),
|
||||||
|
Index: map[string]*ctx.Context{
|
||||||
|
"void": &ctx.Context{Name: "void",
|
||||||
|
Commands: map[string]*ctx.Command{
|
||||||
|
"open": &ctx.Command{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
1362
src/context/ctx.go
1362
src/context/ctx.go
File diff suppressed because it is too large
Load Diff
@ -27,32 +27,32 @@ func (mdb *MDB) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { // {{{
|
func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
mdb.Capi("nsource", 1)
|
m.Capi("nsource", 1)
|
||||||
defer mdb.Capi("nsource", -1)
|
defer m.Capi("nsource", -1)
|
||||||
|
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
mdb.Conf("source", arg[0])
|
m.Conf("source", arg[0])
|
||||||
|
|
||||||
if len(arg) > 1 {
|
if len(arg) > 1 {
|
||||||
mdb.Conf("driver", arg[1])
|
m.Conf("driver", arg[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if mdb.Conf("source") == "" || mdb.Conf("driver") == "" {
|
if m.Conf("source") == "" || m.Conf("driver") == "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
db, e := sql.Open(mdb.Conf("driver"), mdb.Conf("source"))
|
db, e := sql.Open(m.Conf("driver"), m.Conf("source"))
|
||||||
mdb.Assert(e)
|
m.Assert(e)
|
||||||
mdb.db = db
|
mdb.db = db
|
||||||
defer mdb.db.Close()
|
defer mdb.db.Close()
|
||||||
|
|
||||||
log.Println(mdb.Name, "open:", mdb.Conf("driver"), mdb.Conf("source"))
|
log.Println(mdb.Name, "open:", m.Conf("driver"), m.Conf("source"))
|
||||||
defer log.Println(mdb.Name, "close:", mdb.Conf("driver"), mdb.Conf("source"))
|
defer log.Println(mdb.Name, "close:", m.Conf("driver"), m.Conf("source"))
|
||||||
|
|
||||||
for _, p := range m.Meta["prepare"] {
|
for _, p := range m.Meta["prepare"] {
|
||||||
_, e := db.Exec(p)
|
_, e := db.Exec(p)
|
||||||
mdb.Assert(e)
|
m.Assert(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -86,7 +86,7 @@ var Index = &ctx.Context{Name: "mdb", Help: "内存数据库",
|
|||||||
"prepare": "打开数据库时自动执行的语句",
|
"prepare": "打开数据库时自动执行的语句",
|
||||||
},
|
},
|
||||||
Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
m.Start("db"+c.Cap("nsource"), arg...) // {{{
|
m.Start("db"+m.Cap("nsource"), arg...) // {{{
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
|
@ -9,37 +9,41 @@ import ( // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
type TCP struct {
|
type TCP struct {
|
||||||
listener net.Listener
|
l net.Listener
|
||||||
|
c net.Conn
|
||||||
|
close bool
|
||||||
*ctx.Context
|
*ctx.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||||
tcp.Caches["nclient"] = &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"}
|
|
||||||
return tcp
|
return tcp
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{
|
func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
if tcp.Conf("address") == "" {
|
if arg[0] == "dial" {
|
||||||
|
c, e := net.Dial(m.Conf("protocol"), m.Conf("address"))
|
||||||
|
m.Assert(e)
|
||||||
|
tcp.c = c
|
||||||
|
|
||||||
|
log.Printf("%s dial(%d): %v->%v", tcp.Name, m.Capi("nclient", 1), c.LocalAddr(), c.RemoteAddr())
|
||||||
|
m.Reply(c.LocalAddr().String()).Put("option", "io", c).Cmd("open")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
l, e := net.Listen("tcp4", tcp.Conf("address"))
|
l, e := net.Listen(m.Conf("protocol"), m.Conf("address"))
|
||||||
tcp.Assert(e)
|
m.Assert(e)
|
||||||
tcp.listener = l
|
tcp.l = l
|
||||||
|
|
||||||
log.Printf("%s listen(%d): %v", tcp.Name, tcp.Capi("nlisten", 1), l.Addr())
|
log.Printf("%s listen(%d): %v", tcp.Name, m.Capi("nlisten", 1), l.Addr())
|
||||||
defer tcp.Capi("nlisten", -1)
|
defer m.Capi("nlisten", -1)
|
||||||
defer log.Println("%s close(%d): %v", tcp.Name, tcp.Capi("nlisten", 0), l.Addr())
|
defer log.Println("%s close(%d): %v", tcp.Name, m.Capi("nlisten"), l.Addr())
|
||||||
|
|
||||||
for {
|
for {
|
||||||
c, e := l.Accept()
|
c, e := l.Accept()
|
||||||
tcp.Assert(e)
|
m.Assert(e)
|
||||||
log.Printf("%s accept(%d): %v<-%v", tcp.Name, tcp.Capi("nclient", 1), c.LocalAddr(), c.RemoteAddr())
|
log.Printf("%s accept(%d): %v<-%v", tcp.Name, m.Capi("nclient", 1), c.LocalAddr(), c.RemoteAddr())
|
||||||
// defer log.Println(tcp.Name, "close:", tcp.Capi("nclient", -1), c.LocalAddr(), "<-", c.RemoteAddr())
|
m.Reply(c.RemoteAddr().String()).Put("option", "io", c).Cmd("open")
|
||||||
|
|
||||||
msg := m.Spawn(m.Context, c.RemoteAddr().String()).Put("option", "io", c)
|
|
||||||
msg.Cmd("open", c.RemoteAddr().String(), "tcp")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -48,8 +52,19 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
func (tcp *TCP) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{
|
func (tcp *TCP) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||||
c.Caches = map[string]*ctx.Cache{}
|
c.Caches = map[string]*ctx.Cache{}
|
||||||
c.Configs = map[string]*ctx.Config{
|
c.Configs = map[string]*ctx.Config{}
|
||||||
"address": &ctx.Config{Name: "address", Value: arg[0], Help: "监听地址"},
|
|
||||||
|
if len(arg) > 1 {
|
||||||
|
switch arg[0] {
|
||||||
|
case "listen":
|
||||||
|
c.Caches["nclient"] = &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"}
|
||||||
|
c.Configs["address"] = &ctx.Config{Name: "address", Value: arg[1], Help: "监听地址"}
|
||||||
|
case "dial":
|
||||||
|
c.Configs["address"] = &ctx.Config{Name: "address", Value: arg[1], Help: "连接地址"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(arg) > 2 {
|
||||||
|
c.Configs["security"] = &ctx.Config{Name: "security(true/false)", Value: "true", Help: "加密通信"}
|
||||||
}
|
}
|
||||||
|
|
||||||
s := new(TCP)
|
s := new(TCP)
|
||||||
@ -60,18 +75,28 @@ func (tcp *TCP) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (tcp *TCP) Exit(m *ctx.Message, arg ...string) bool { // {{{
|
func (tcp *TCP) Exit(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
|
switch tcp.Context {
|
||||||
|
case m.Source:
|
||||||
|
c, ok := m.Data["io"].(net.Conn)
|
||||||
|
if !ok {
|
||||||
|
c = tcp.c
|
||||||
|
}
|
||||||
|
if c != nil {
|
||||||
|
log.Println(tcp.Name, "close:", c.LocalAddr(), "--", c.RemoteAddr())
|
||||||
|
c.Close()
|
||||||
|
}
|
||||||
|
|
||||||
if c, ok := m.Data["result"].(net.Conn); ok && m.Target == tcp.Context {
|
case m.Target:
|
||||||
c.Close()
|
if tcp.l != nil {
|
||||||
delete(m.Data, "result")
|
log.Println(tcp.Name, "close:", tcp.l.Addr())
|
||||||
return true
|
tcp.l.Close()
|
||||||
|
}
|
||||||
|
if tcp.c != nil {
|
||||||
|
log.Println(tcp.Name, "close:", tcp.c.LocalAddr(), "->", tcp.c.RemoteAddr())
|
||||||
|
tcp.c.Close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c, ok := m.Data["detail"].(net.Conn); ok && m.Context == tcp.Context {
|
|
||||||
c.Close()
|
|
||||||
delete(m.Data, "detail")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,36 +104,40 @@ func (tcp *TCP) Exit(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
|
|
||||||
var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
|
var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
|
||||||
Caches: map[string]*ctx.Cache{
|
Caches: map[string]*ctx.Cache{
|
||||||
"nlisten": &ctx.Cache{Name: "nlisten", Value: "0", Help: "连接数量"},
|
"nlisten": &ctx.Cache{Name: "nlisten", Value: "0", Help: "监听数量"},
|
||||||
|
"nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"},
|
||||||
},
|
},
|
||||||
Configs: map[string]*ctx.Config{
|
Configs: map[string]*ctx.Config{
|
||||||
"address": &ctx.Config{Name: "address", Value: "", Help: "监听地址"},
|
"protocol": &ctx.Config{Name: "protocol(tcp/tcp4/tcp6)", Value: "tcp4", Help: "连接协议"},
|
||||||
|
"security": &ctx.Config{Name: "security(true/false)", Value: "false", Help: "加密通信"},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
"listen": &ctx.Command{Name: "listen address", Help: "监听连接", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"listen": &ctx.Command{Name: "listen [address [security]]", Help: "监听连接", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
switch len(arg) { // {{{
|
switch len(arg) { // {{{
|
||||||
case 0:
|
case 0:
|
||||||
for k, s := range m.Target.Contexts {
|
m.Travel(m.Target, func(m *ctx.Message) bool {
|
||||||
m.Echo("%s %s\n", k, s.Server.(*TCP).listener.Addr().String())
|
if tcp, ok := m.Target.Server.(*TCP); ok && tcp.l != nil {
|
||||||
}
|
m.Echo("%s %v\n", m.Target.Name, tcp.l.Addr())
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
case 1:
|
case 1:
|
||||||
go m.Start(arg[0], arg[0])
|
go m.Start(arg[0], m.Meta["detail"]...)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"dial": &ctx.Command{Name: "dial", Help: "建立连接", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"dial": &ctx.Command{Name: "dial [address [security]]", Help: "建立连接", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
tcp := c.Server.(*TCP) // {{{
|
switch len(arg) { // {{{
|
||||||
switch len(arg) {
|
|
||||||
case 0:
|
case 0:
|
||||||
for i, v := range tcp.Requests {
|
m.Travel(m.Target, func(m *ctx.Message) bool {
|
||||||
conn := v.Data["result"].(net.Conn)
|
if tcp, ok := m.Target.Server.(*TCP); ok && tcp.c != nil {
|
||||||
m.Echo(tcp.Name, "conn: %s %s -> %s\n", i, conn.LocalAddr(), conn.RemoteAddr())
|
m.Echo("%s %v->%v\n", m.Target.Name, tcp.c.LocalAddr(), tcp.c.RemoteAddr())
|
||||||
}
|
}
|
||||||
case 2:
|
return true
|
||||||
conn, e := net.Dial("tcp", arg[0])
|
})
|
||||||
c.Assert(e)
|
case 1:
|
||||||
log.Println(tcp.Name, "dial:", conn.LocalAddr(), "->", conn.RemoteAddr())
|
m.Start(arg[0], m.Meta["detail"]...)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
@ -116,7 +145,7 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
|
|||||||
"exit": &ctx.Command{Name: "exit", Help: "退出", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"exit": &ctx.Command{Name: "exit", Help: "退出", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
tcp, ok := m.Target.Server.(*TCP) // {{{
|
tcp, ok := m.Target.Server.(*TCP) // {{{
|
||||||
if !ok {
|
if !ok {
|
||||||
tcp, ok = m.Context.Server.(*TCP)
|
tcp, ok = m.Source.Server.(*TCP)
|
||||||
}
|
}
|
||||||
if ok {
|
if ok {
|
||||||
tcp.Context.Exit(m)
|
tcp.Context.Exit(m)
|
||||||
@ -126,6 +155,13 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
|
|||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
Index: map[string]*ctx.Context{
|
||||||
|
"void": &ctx.Context{
|
||||||
|
Commands: map[string]*ctx.Command{
|
||||||
|
"listen": &ctx.Command{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user