1
0
forked from x/ContextOS

mac add context.deal

添加消息处理,异常链,函数链,简化了模块创建与消息派生的操作接口
This commit is contained in:
shaoying 2017-11-05 02:04:57 +08:00
parent 5a692b1aa5
commit 585ee2434b
4 changed files with 316 additions and 222 deletions

View File

@ -1,14 +1,11 @@
package cli // {{{ package cli
// }}}
import ( // {{{ import ( // {{{
"bufio" "bufio"
"context" "context"
"fmt" "fmt"
"io" "io"
"log"
"os" "os"
"os/exec"
"runtime/debug"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -26,8 +23,8 @@ type CLI struct {
history []map[string]string history []map[string]string
alias map[string]string alias map[string]string
exit chan bool
next string next string
exit bool
target *ctx.Context target *ctx.Context
*ctx.Context *ctx.Context
@ -58,6 +55,7 @@ func (cli *CLI) parse() bool { // {{{
l := len(cli.ins) l := len(cli.ins)
if l == 1 { if l == 1 {
cli.echo("\n%s\n", cli.Conf("结束语")) cli.echo("\n%s\n", cli.Conf("结束语"))
return false
ls = "exit" ls = "exit"
e = nil e = nil
} else { } else {
@ -125,8 +123,7 @@ func (cli *CLI) parse() bool { // {{{
} }
} }
log.Printf("%d spawn: %s->%s %v", cli.Resource[0].Code, msg.Context.Name, msg.Target.Name, msg.Meta["detail"]) msg.Post(cli.Context)
cli.Post(msg)
for _, v := range msg.Meta["result"] { for _, v := range msg.Meta["result"] {
cli.echo(v) cli.echo(v)
@ -135,53 +132,6 @@ func (cli *CLI) parse() bool { // {{{
return true return true
} }
// }}}
func (cli *CLI) deal(msg *ctx.Message) bool { // {{{
defer func() {
if e := recover(); e != nil {
msg.Echo("%s\n", e)
if e == io.EOF {
panic(e)
} else {
debug.PrintStack()
log.Println(e)
msg.End(false)
}
}
}()
detail := msg.Meta["detail"]
if len(detail) == 0 {
msg.End(true)
return true
}
if a, ok := cli.alias[detail[0]]; ok {
detail[0] = a
}
if _, ok := cli.Commands[detail[0]]; ok {
cli.next = cli.Cmd(msg, detail...)
} else if _, ok := msg.Target.Commands[detail[0]]; ok {
cli.next = msg.Cmd()
} else {
cmd := exec.Command(detail[0], detail[1:]...)
v, e := cmd.CombinedOutput()
if e != nil {
msg.Echo("%s\n", e)
}
msg.Echo(string(v))
}
msg.End(true)
cli.history = append(cli.history, map[string]string{
"time": time.Now().Format("15:04:05"),
"index": fmt.Sprintf("%d", len(cli.history)),
"cli": strings.Join(detail, " "),
})
return true
}
// }}} // }}}
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 || cli.Conf("slient") != "yes" {
@ -191,18 +141,15 @@ func (cli *CLI) echo(str string, arg ...interface{}) { // {{{
// }}} // }}}
func (cli *CLI) Begin() ctx.Server { // {{{ func (cli *CLI) Begin(m *ctx.Message) ctx.Server { // {{{
cli.history = make([]map[string]string, 0, 100) cli.history = make([]map[string]string, 0, 100)
cli.alias = make(map[string]string, 10) cli.alias = make(map[string]string, 10)
cli.exit = make(chan bool)
cli.target = cli.Context cli.target = cli.Context
return cli.Server return cli.Server
} }
// }}} // }}}
func (cli *CLI) Start(m *ctx.Message) bool { // {{{ func (cli *CLI) Start(m *ctx.Message) bool { // {{{
if detail, ok := m.Data["detail"]; ok { if detail, ok := m.Data["detail"]; ok {
io := detail.(io.ReadWriteCloser) io := detail.(io.ReadWriteCloser)
cli.out = io cli.out = io
@ -214,21 +161,40 @@ func (cli *CLI) Start(m *ctx.Message) bool { // {{{
cli.push(f) cli.push(f)
} }
go func() { go cli.Safe(m, func(c *ctx.Context, m *ctx.Message) {
defer recover()
for cli.parse() { for cli.parse() {
} }
}() })
} }
for cli.deal(cli.Get()) { for cli.Deal(func(msg *ctx.Message) bool {
arg := msg.Meta["detail"]
if a, ok := cli.alias[arg[0]]; ok {
arg[0] = a
}
return true
}, func(msg *ctx.Message) bool {
arg := msg.Meta["detail"]
cli.history = append(cli.history, map[string]string{
"time": time.Now().Format("15:04:05"),
"index": fmt.Sprintf("%d", len(cli.history)),
"cli": strings.Join(arg, " "),
})
if cli.exit == true {
return false
}
return true
}) {
} }
return true return true
} }
// }}} // }}}
func (cli *CLI) Spawn(c *ctx.Context, arg ...string) ctx.Server { // {{{ 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{
"status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"}, "status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"},
} }
@ -244,6 +210,14 @@ func (cli *CLI) Spawn(c *ctx.Context, arg ...string) ctx.Server { // {{{
return s return s
} }
// }}}
func (cli *CLI) Exit(m *ctx.Message, arg ...string) bool { // {{{
if cli.Context != Index {
delete(cli.Context.Context.Contexts, cli.Name)
}
return true
}
// }}} // }}}
var Index = &ctx.Context{Name: "cli", Help: "本地控制", var Index = &ctx.Context{Name: "cli", Help: "本地控制",
@ -303,18 +277,19 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
msg.Target = msg.Context msg.Target = msg.Context
} }
default: default:
if cs := msg.Target.Find(strings.Split(arg[1], ".")); cs != nil { // if cs := msg.Target.Find(strings.Split(arg[1], ".")); cs != nil {
if cs := c.Root.Search(arg[1]); cs != nil && len(cs) > 0 {
if ok { if ok {
cli.target = cs cli.target = cs[0]
} else { } else {
msg.Target = cs msg.Target = cs[0]
} }
} }
} }
case 3, 4: case 3, 4:
switch arg[1] { switch arg[1] {
case "spawn": case "spawn":
msg.Target.Spawn(arg[2]) msg.Target.Spawn(msg, arg[2])
case "find": case "find":
cs := msg.Target.Find(strings.Split(arg[2], ".")) cs := msg.Target.Find(strings.Split(arg[2], "."))
if cs != nil { if cs != nil {
@ -505,7 +480,19 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
// }}} // }}}
}}, }},
"exit": &ctx.Command{"exit", "退出", func(c *ctx.Context, m *ctx.Message, arg ...string) string { "exit": &ctx.Command{"exit", "退出", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
panic(io.EOF) 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 ""
}}, }},
"remote": &ctx.Command{"remote master|slave listen|dial address protocol", "建立远程连接", func(c *ctx.Context, m *ctx.Message, arg ...string) string { "remote": &ctx.Command{"remote master|slave listen|dial address protocol", "建立远程连接", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
switch len(arg) { // {{{ switch len(arg) { // {{{
@ -518,7 +505,7 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
} else { } else {
if arg[2] == "listen" { if arg[2] == "listen" {
s := c.Root.Find(strings.Split(arg[4], ".")) s := c.Root.Find(strings.Split(arg[4], "."))
m.Message.Spawn(s, arg[3], 0).Add("detail", "listen", arg[3]).Post(c) m.Message.Spawn(s, arg[3]).Cmd("listen", arg[3])
} else { } else {
} }
} }

View File

@ -1,10 +1,12 @@
package ctx // {{{ package ctx
// }}}
import ( // {{{ import ( // {{{
"errors" "errors"
"fmt" "fmt"
"io"
"log" "log"
"os" "os"
"os/exec"
"regexp" "regexp"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
@ -46,24 +48,25 @@ type Message struct { // {{{
Data map[string]interface{} Data map[string]interface{}
Wait chan bool Wait chan bool
Name string
*Context *Context
Name string
Target *Context
Index int Index int
Target *Context
Messages []*Message Messages []*Message
Message *Message Message *Message
Root *Message Root *Message
} }
func (m *Message) Spawn(c *Context, key string, index int) *Message { // {{{ func (m *Message) Spawn(c *Context, key string) *Message { // {{{
msg := &Message{ msg := &Message{
Code: m.Capi("nmessage", 1), Code: m.Capi("nmessage", 1),
Time: time.Now(), Time: time.Now(),
Target: c,
Name: key, Name: key,
Index: 0,
Target: c,
Message: m, Message: m,
Root: m.Root, Root: Pulse,
} }
msg.Context = m.Target msg.Context = m.Target
@ -82,6 +85,7 @@ func (m *Message) Spawn(c *Context, key string, index int) *Message { // {{{
} }
// }}} // }}}
func (m *Message) Add(key string, value ...string) *Message { // {{{ func (m *Message) Add(key string, value ...string) *Message { // {{{
if m.Meta == nil { if m.Meta == nil {
m.Meta = make(map[string][]string) m.Meta = make(map[string][]string)
@ -132,8 +136,7 @@ func (m *Message) Echo(str string, arg ...interface{}) *Message { // {{{
m.Meta["result"] = make([]string, 0, 3) m.Meta["result"] = make([]string, 0, 3)
} }
s := fmt.Sprintf(str, arg...) m.Meta["result"] = append(m.Meta["result"], fmt.Sprintf(str, arg...))
m.Meta["result"] = append(m.Meta["result"], s)
return m return m
} }
@ -146,12 +149,25 @@ func (m *Message) End(s bool) { // {{{
} }
// }}} // }}}
func (m *Message) Cmd() string { // {{{
func (m *Message) Cmd(arg ...string) string { // {{{
if len(arg) > 0 {
if m.Meta == nil {
m.Meta = make(map[string][]string)
}
m.Meta["detail"] = arg
}
log.Printf("%s command(%s->%s): %v", m.Target.Name, m.Context.Name, m.Target.Name, m.Meta["detail"])
return m.Target.Cmd(m, m.Meta["detail"]...) return m.Target.Cmd(m, m.Meta["detail"]...)
} }
// }}} // }}}
func (m *Message) Post(c *Context) bool { // {{{ func (m *Message) Post(c *Context, arg ...string) bool { // {{{
if len(arg) > 0 {
m.Meta["detail"] = arg
}
if c.Messages == nil { if c.Messages == nil {
c.Messages = make(chan *Message, c.Confi("MessageQueueSize")) c.Messages = make(chan *Message, c.Confi("MessageQueueSize"))
} }
@ -166,22 +182,26 @@ func (m *Message) Post(c *Context) bool { // {{{
// }}} // }}}
func (m *Message) Start(arg ...string) bool { // {{{ func (m *Message) Start(arg ...string) bool { // {{{
s := m.Target.Spawn(arg...).Begin() if len(arg) > 0 {
m.Target = s m.Meta["detail"] = arg
go s.Start(m) }
go m.Target.Spawn(m, m.Meta["detail"]...).Begin(m).Start(m)
return true return true
} }
// }}} // }}}
// }}} // }}}
type Server interface { // {{{ type Server interface { // {{{
Begin() Server Begin(m *Message) Server
Start(m *Message) bool Start(m *Message) bool
Spawn(c *Context, arg ...string) Server Spawn(c *Context, m *Message, arg ...string) Server
Exit(m *Message, arg ...string) bool
} }
// }}} // }}}
type Context struct { // {{{ type Context struct {
Name string Name string
Help string Help string
@ -207,78 +227,182 @@ type Context struct { // {{{
func (c *Context) Check(e error) bool { // {{{ func (c *Context) Check(e error) bool { // {{{
if e != nil { if e != nil {
log.Println(c.Name, "error:", e) log.Println(c.Name, "error:", e)
if c.Conf("debug") == "on" {
debug.PrintStack()
}
panic(e) panic(e)
} }
return true return true
} }
// }}} // }}}
func (c *Context) Register(s *Context, self Server) bool { // {{{ func (c *Context) Safe(m *Message, hand ...func(c *Context, m *Message)) (ok bool) { // {{{
defer func() {
if e := recover(); e != nil {
if c.Conf("debug") == "on" {
log.Println(c.Name, "error:", e)
if e != io.EOF {
debug.PrintStack()
}
}
if e == io.EOF {
return
}
if len(hand) > 0 {
c.Safe(m, hand[1:]...)
}
}
Pulse.Wait <- true
}()
if len(hand) > 0 {
hand[0](c, m)
}
return true
}
// }}}
func (c *Context) Register(s *Context, x Server) *Context { // {{{
if c.Contexts == nil { if c.Contexts == nil {
c.Contexts = make(map[string]*Context) c.Contexts = make(map[string]*Context)
} }
if x, ok := c.Contexts[s.Name]; ok { if x, ok := c.Contexts[s.Name]; ok {
panic(errors.New(c.Name + " 上下文已存在" + x.Name)) panic(errors.New(c.Name + " 上下文已存在" + x.Name))
} }
c.Contexts[s.Name] = s c.Contexts[s.Name] = s
s.Context = c
s.Root = c.Root s.Root = c.Root
s.Server = self s.Context = c
s.Server = x
log.Printf("%s register(%d): %s", c.Name, Index.Capi("ncontext", 1), s.Name)
return s
}
// }}}
func (c *Context) Begin(m *Message) *Context { // {{{
for _, v := range c.Configs {
if v.Hand != nil {
v.Hand(c, v.Value)
log.Println(c.Name, "config:", v.Name, v.Value)
}
}
if c.Server != nil {
c.Server.Begin(m)
}
return c
}
// }}}
func (c *Context) Start(m *Message) bool { // {{{
if c.Server != nil && c.Cap("status") != "start" {
c.Safe(m, func(c *Context, m *Message) {
c.Cap("status", "start")
defer c.Cap("status", "stop")
log.Printf("%d start(%d): %s", m.Code, Index.Capi("nserver", 1), c.Name)
defer Index.Capi("nserver", -1)
defer log.Printf("%d stop(%d): %s %s", m.Code, Index.Capi("nserver", 0), c.Name, c.Help)
c.Resource = []*Message{m}
c.Server.Start(m)
})
}
log.Println(c.Name, "register:", s.Name)
return true return true
} }
// }}} // }}}
func (c *Context) Init(arg ...string) { // {{{ func (c *Context) Spawn(m *Message, arg ...string) *Context { // {{{
if c.Root != nil { s := &Context{Name: arg[0], Help: c.Help}
return m.Target = s
} c.Register(s, c.Server.Spawn(s, m, arg...)).Begin(m)
return s
root := c
for root.Context != nil {
root = root.Context
}
cs := []*Context{root}
for i := 0; i < len(cs); i++ {
cs[i].Root = root
cs[i].Begin()
for _, v := range cs[i].Contexts {
cs = append(cs, v)
}
}
Pulse.Root = Pulse
Pulse.Target = Index
Pulse.Context = Index
for _, s := range root.Contexts {
if ok, _ := regexp.MatchString(root.Conf("start"), s.Name); ok {
go s.Start(Pulse.Spawn(s, s.Name, 0).Put("detail", os.Stdout))
}
}
Pulse.Wait = make(chan bool)
for {
<-Pulse.Wait
if Index.Capi("nserver", 0) == 0 {
return
}
}
} }
// }}} // }}}
func (c *Context) Find(name []string) (s *Context) { // {{{ func (c *Context) Deal(pre func(m *Message) bool, post func(m *Message) bool) (live bool) { // {{{
log.Println(c.Name, "find:", name)
if c.Messages == nil {
c.Messages = make(chan *Message, c.Confi("MessageQueueSize"))
}
m := <-c.Messages
defer m.End(true)
if len(m.Meta["detail"]) == 0 {
return true
}
if pre != nil && !pre(m) {
return false
}
c.Safe(m, func(c *Context, m *Message) {
c.Cmd(m, m.Meta["detail"]...)
log.Printf("%s command(%s->%s): %v", c.Name, m.Context.Name, m.Target.Name, m.Meta["detail"])
}, func(c *Context, m *Message) {
m.Cmd()
}, func(c *Context, m *Message) {
log.Printf("system command(%s->%s): %v", m.Context.Name, m.Target.Name, m.Meta["detail"])
arg := m.Meta["detail"]
cmd := exec.Command(arg[0], arg[1:]...)
v, e := cmd.CombinedOutput()
if e != nil {
m.Echo("%s\n", e)
} else {
m.Echo(string(v))
}
})
if post != nil && !post(m) {
return false
}
return true
}
// }}}
func (c *Context) Exit(m *Message, arg ...string) { // {{{
if m.Target == c {
for _, v := range c.Session {
if v.Name != "" {
c.Server.Exit(v, arg...)
v.Name = ""
log.Println(c.Name, c.Help, "exit: session", v.Code, v.Target.Name, v.Target.Help)
v.Cmd("exit")
}
}
for _, v := range c.Resource {
if v.Index != -1 {
c.Server.Exit(v, arg...)
v.Index = -1
log.Println(c.Name, c.Help, "exit: resource", v.Code, v.Context.Name, v.Context.Help)
v.Context.Cmd(v, "exit")
}
}
} else if m.Context == c {
if m.Name != "" {
c.Server.Exit(m, arg...)
m.Name = ""
m.Cmd("exit")
}
} else {
c.Server.Exit(m, arg...)
}
}
// }}}
func (c *Context) Find(name []string) (s *Context) { // {{{
cs := c.Contexts cs := c.Contexts
for _, v := range name { for _, v := range name {
if x, ok := cs[v]; ok { if x, ok := cs[v]; ok {
@ -478,79 +602,6 @@ func (c *Context) Del(arg ...string) { // {{{
// }}} // }}}
func (c *Context) Begin() *Context { // {{{
c.Root.Capi("ncontext", 1)
for _, v := range c.Configs {
if v.Hand != nil {
v.Hand(c, v.Value)
}
}
if c.Server != nil {
c.Server.Begin()
}
return c
}
// }}}
func (c *Context) Start(m *Message) bool { // {{{
defer func() {
if e := recover(); e != nil {
log.Println(e)
}
Pulse.Wait <- true
}()
if c.Server != nil && c.Cap("status") != "start" {
c.Cap("status", "status", "start", "服务状态")
defer c.Cap("status", "stop")
c.Root.Capi("nserver", 1)
defer c.Root.Capi("nserver", -1)
c.Resource = []*Message{m}
log.Println(m.Code, "start:", c.Name)
c.Server.Start(m)
log.Println(m.Code, "stop:", c.Name)
}
return true
}
// }}}
func (c *Context) Spawn(arg ...string) *Context { // {{{
s := &Context{Name: arg[0], Help: c.Help}
c.Register(s, c.Server.Spawn(s, arg...))
s.Begin()
return s
}
// }}}
func (c *Context) Post(m *Message) bool { // {{{
if c.Messages == nil {
c.Messages = make(chan *Message, c.Confi("MessageQueueSize"))
}
c.Messages <- m
if m.Wait != nil {
return <-m.Wait
}
return true
}
// }}}
func (c *Context) Get() *Message { // {{{
if c.Messages == nil {
c.Messages = make(chan *Message, c.Confi("MessageQueueSize"))
}
return <-c.Messages
}
// }}}
func (c *Context) Cmd(m *Message, arg ...string) string { // {{{ func (c *Context) Cmd(m *Message, arg ...string) string { // {{{
if x, ok := c.Commands[arg[0]]; ok { if x, ok := c.Commands[arg[0]]; ok {
return x.Hand(c, m, arg...) return x.Hand(c, m, arg...)
@ -663,7 +714,6 @@ func (c *Context) Capi(key string, value int) int { // {{{
return n + value return n + value
} }
// }}}
// }}} // }}}
var Index = &Context{Name: "ctx", Help: "根上下文", var Index = &Context{Name: "ctx", Help: "根上下文",
@ -683,7 +733,7 @@ var Index = &Context{Name: "ctx", Help: "根上下文",
"cert": &Config{Name: "cert", Value: "etc/cert.pem", Help: "证书文件"}, "cert": &Config{Name: "cert", Value: "etc/cert.pem", Help: "证书文件"},
"key": &Config{Name: "key", Value: "etc/key.pem", Help: "私钥文件"}, "key": &Config{Name: "key", Value: "etc/key.pem", Help: "私钥文件"},
"debug": &Config{Name: "debug", Value: "on", Help: "调试模式"}, "debug": &Config{Name: "debug", Value: "off", Help: "调试模式"},
"start": &Config{Name: "start", Value: "cli", Help: "默认启动模块"}, "start": &Config{Name: "start", Value: "cli", Help: "默认启动模块"},
"init.sh": &Config{Name: "init.sh", Value: "etc/init.sh", Help: "默认启动脚本"}, "init.sh": &Config{Name: "init.sh", Value: "etc/init.sh", Help: "默认启动脚本"},
"bench.log": &Config{Name: "bench.log", Value: "var/bench.log", Help: "默认日志文件", Hand: func(c *Context, arg string) string { "bench.log": &Config{Name: "bench.log", Value: "var/bench.log", Help: "默认日志文件", Hand: func(c *Context, arg string) string {
@ -715,8 +765,35 @@ func init() {
if len(os.Args) > 3 { if len(os.Args) > 3 {
Index.Conf("start", os.Args[3]) Index.Conf("start", os.Args[3])
} }
log.Println("\n\n\n")
} }
func Start() { func Start() {
Index.Init() Pulse.Root = Pulse
Pulse.Target = Index
Pulse.Context = Index
Pulse.Wait = make(chan bool, 10)
cs := []*Context{Index}
for i := 0; i < len(cs); i++ {
cs[i].Root = Index
cs[i].Begin(nil)
for _, v := range cs[i].Contexts {
cs = append(cs, v)
}
}
for _, s := range Index.Contexts {
if ok, _ := regexp.MatchString(Index.Conf("start"), s.Name); ok {
go s.Start(Pulse.Spawn(s, s.Name).Put("detail", os.Stdout))
}
}
for {
<-Pulse.Wait
if Index.Capi("nserver", 0) == 0 {
return
}
}
} }

View File

@ -1,5 +1,5 @@
package tcp // {{{ package tcp
// }}}
import ( // {{{ import ( // {{{
"context" "context"
"log" "log"
@ -13,7 +13,7 @@ type TCP struct {
*ctx.Context *ctx.Context
} }
func (tcp *TCP) Begin() ctx.Server { // {{{ func (tcp *TCP) Begin(m *ctx.Message) ctx.Server { // {{{
return tcp return tcp
} }
@ -26,25 +26,29 @@ func (tcp *TCP) Start(m *ctx.Message) bool { // {{{
l, e := net.Listen("tcp", tcp.Conf("address")) l, e := net.Listen("tcp", tcp.Conf("address"))
tcp.Check(e) tcp.Check(e)
tcp.listener = l tcp.listener = l
tcp.Capi("nlisten", 1)
log.Println(tcp.Name, "listen:", l.Addr()) log.Printf("%s listen(%d): %v", tcp.Name, tcp.Capi("nlisten", 1), l.Addr())
defer tcp.Capi("nlisten", -1)
defer log.Println("%s close(%d): %v", tcp.Name, tcp.Capi("nlisten", 0), l.Addr())
for { for {
c, e := l.Accept() c, e := l.Accept()
log.Println(tcp.Name, "accept:", c.LocalAddr(), "<-", c.RemoteAddr())
tcp.Check(e) tcp.Check(e)
log.Printf("%s accept(%d): %v<-%v", tcp.Name, tcp.Capi("nclient", 1), c.LocalAddr(), c.RemoteAddr())
// defer log.Println(tcp.Name, "close:", tcp.Capi("nclient", -1), c.LocalAddr(), "<-", c.RemoteAddr())
m := m.Spawn(m.Context, c.RemoteAddr().String(), 0) msg := m.Spawn(m.Context, c.RemoteAddr().String()).Put("detail", c)
m.Add("detail", "accept", c.RemoteAddr().String(), "tcp").Put("detail", c).Cmd() msg.Cmd("accept", c.RemoteAddr().String(), "tcp")
} }
return true return true
} }
// }}} // }}}
func (tcp *TCP) Spawn(c *ctx.Context, 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{
"nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"}, "nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"},
"status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"},
} }
c.Configs = map[string]*ctx.Config{ c.Configs = map[string]*ctx.Config{
"address": &ctx.Config{Name: "address", Value: arg[0], Help: "监听地址"}, "address": &ctx.Config{Name: "address", Value: arg[0], Help: "监听地址"},
@ -56,6 +60,23 @@ func (tcp *TCP) Spawn(c *ctx.Context, arg ...string) ctx.Server { // {{{
} }
// }}}
func (tcp *TCP) Exit(m *ctx.Message, arg ...string) bool { // {{{
if c, ok := m.Data["result"].(net.Conn); ok && m.Target == tcp.Context {
c.Close()
delete(m.Data, "result")
return true
}
if c, ok := m.Data["detail"].(net.Conn); ok && m.Context == tcp.Context {
c.Close()
delete(m.Data, "detail")
return true
}
return true
}
// }}} // }}}
var Index = &ctx.Context{Name: "tcp", Help: "网络连接", var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
@ -95,6 +116,17 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
return "" return ""
// }}} // }}}
}}, }},
"exit": &ctx.Command{"exit", "退出", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
tcp, ok := m.Target.Server.(*TCP)
if !ok {
tcp, ok = m.Context.Server.(*TCP)
}
if ok {
tcp.Context.Exit(m)
}
return ""
}},
}, },
} }

View File

@ -4,8 +4,6 @@ import (
"context" "context"
_ "context/cli" _ "context/cli"
_ "context/tcp" _ "context/tcp"
// _ "context/ssh"
// _ "context/web"
) )
func main() { func main() {