diff --git a/README.md b/README.md index 6807b212..417ced47 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,17 @@ context: 通过提供自由的模块,简洁的接口,动态的结构,让 * 配置管理config * 缓存管理cache +* Cap() Conf() Cmd() +* Spawn() Begin() Start() Close() + +* Request[] History[] Session[] +* detail[] option[] result[] append[] + +* Context Master Owner +* Search() Action() Assert() Figure() + + + ## 结构设计 * 功能树 * 权限树 diff --git a/etc/init.sh b/etc/init.sh index 16510fb5..9f7bdbc2 100644 --- a/etc/init.sh +++ b/etc/init.sh @@ -1,26 +1,25 @@ # ~lex source etc/lex.sh ~cli @lex lex +~root aaa login root root +# ~tcp listen ":9393" +# ~tcp dial ":9393" +~cli remote slaver listen ":9393" tcp +# @debug on ~mdb open chat chat "chat:chat@/chat" mysql +~web listen +return -~root aaa login root root @debug ~web spawn hi he ./ -~web listen route template /tpl ./usr/msg.tpl route script /php ./usr/msg.php route script /who who ~hi listen ./ ":9494" master nice -pwd - -# ~aaa login shy shy - return login shy shy -~root cli -remote slaver listen ":9393" tcp diff --git a/src/context/aaa/aaa.go b/src/context/aaa/aaa.go index 3d8b24d2..98f33b97 100644 --- a/src/context/aaa/aaa.go +++ b/src/context/aaa/aaa.go @@ -64,6 +64,10 @@ func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ // }}} }} + if m.Target == Index { + Pulse = m + } + aaa.Owner = aaa.Context return aaa } @@ -84,15 +88,17 @@ func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { // {{{ - if m.Target == aaa.Context && aaa.Owner == aaa.Context { - if m.Cap("username") != m.Conf("rootname") { - m.Log("info", nil, "logout %s", m.Cap("group"), m.Cap("username")) - m.Capi("nuser", -1) - return true - } + if aaa.Context == Index { + return false } - return false + switch aaa.Context { + case m.Target: + case m.Source: + } + + m.Log("info", nil, "%d logout %s", Pulse.Capi("nuser", -1)+1, m.Cap("username")) + return true } // }}} @@ -136,7 +142,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", if username == m.Conf("rootname") { m.Set("detail", group, username).Target.Start(m) } else if msg := m.Find(username); msg == nil { - m.Start(username, group, group, username) + m.Start(username, "认证用户", group, username) } else { m.Target = msg.Target } @@ -156,6 +162,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }, }, } +var Pulse *ctx.Message func init() { aaa := &AAA{} diff --git a/src/context/cli/cli.go b/src/context/cli/cli.go index acedea8e..b9f8c467 100644 --- a/src/context/cli/cli.go +++ b/src/context/cli/cli.go @@ -25,6 +25,7 @@ type CLI struct { out io.WriteCloser alias map[string]string + back string next string exit bool @@ -83,6 +84,7 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{ if len(cli.ins) > 1 { return true } + line, cli.back = cli.back, "" } } else { line, cli.next = cli.next, "" @@ -144,13 +146,12 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{ msg.Add("detail", ls[i]) } - if msg.Wait = make(chan bool); msg.Target.Master != cli.Context { - msg.Post(msg.Target.Master) - } else { - msg.Post(cli.Context) - } + msg.Wait = make(chan bool) + msg.Post(cli.Context) cli.echo(strings.Join(msg.Meta["result"], "")) + cli.target = msg.Target + cli.back = line return true } @@ -218,11 +219,11 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ m.Assert(lex != nil, "词法解析模块不存在") if lex.Cap("status") != "start" { lex.Target.Start(lex) - lex.Cmd("train", "'[^']*'") - lex.Cmd("train", "\"[^\"]*\"") - lex.Cmd("train", "[^ \t\n]+") - lex.Cmd("train", "[ \n\t]+", "void", "void") - lex.Cmd("train", "#[^\n]*\n", "void", "void") + m.Spawn(lex.Target).Cmd("train", "'[^']*'") + m.Spawn(lex.Target).Cmd("train", "\"[^\"]*\"") + m.Spawn(lex.Target).Cmd("train", "[^ \t\n]+") + m.Spawn(lex.Target).Cmd("train", "[ \n\t]+", "void", "void") + m.Spawn(lex.Target).Cmd("train", "#[^\n]*\n", "void", "void") } cli.lex = lex } @@ -285,6 +286,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ cli.echo("password>") fmt.Fscanln(cli.in, &password) + msg.Wait = make(chan bool) if msg.Cmd("login", username, password) == "" { cli.echo("登录失败") m.Cmd("exit") @@ -292,7 +294,15 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ cli.in.Close() return false } + + if cli.Sessions == nil { + cli.Sessions = make(map[string]*ctx.Message) + } + cli.Sessions["aaa"] = msg + msg.Name = "aaa" } + } else { + m.Cap("stream", "stdout") } m.Log("info", nil, "slaver terminal") @@ -319,7 +329,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ msg.Set("append") c := exec.Command(msg.Meta["detail"][0], msg.Meta["detail"][1:]...) - if len(cli.ins) == 1 { + if len(cli.ins) == 1 && cli.Context == Index { c.Stdin, c.Stdout, c.Stderr = cli.in, cli.out, cli.out msg.Assert(c.Start()) msg.Assert(c.Wait()) @@ -342,20 +352,21 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{ - switch cli.Context { - case m.Source: + if cli.Context == Index { return false - - case m.Target: - m.Log("exit", nil, "release") } - return false + switch cli.Context { + case m.Target: + case m.Source: + } + + return true } // }}} -var Index = &ctx.Context{Name: "cli", Help: "管理终端", +var Index = &ctx.Context{Name: "cli", Help: "管理中心", Caches: map[string]*ctx.Cache{ "nterm": &ctx.Cache{Name: "终端数量", Value: "0", Help: "已经运行的终端数量"}, }, @@ -437,7 +448,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", "open": &ctx.Command{Name: "open [master|slaver] [script [log]]", Help: "建立远程连接", Options: map[string]string{"master": "主控终端", "slaver": "被控终端", "args": "启动参数", "io": "读写流"}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { - m.Start(fmt.Sprintf("PTS%d", m.Capi("nterm")), "管理终端", arg...) // {{{ + m.Start(fmt.Sprintf("PTS%d", m.Capi("nterm")), "管理终端", "void.sh") // {{{ return "" // }}} }}, diff --git a/src/context/ctx.go b/src/context/ctx.go index 5765a499..4c1e871f 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -50,7 +50,6 @@ type Server interface { type Context struct { Name string Help string - Server Caches map[string]*Cache Configs map[string]*Config @@ -61,16 +60,20 @@ type Context struct { root *Context Sessions map[string]*Message + Historys []*Message Requests []*Message - Master *Context messages chan *Message message *Message + Master *Context - Group string - Owner *Context Index map[string]*Context Groups map[string]*Context + Owner *Context + Group string + + Pulse *Message + Server } func (c *Context) Register(s *Context, x Server) *Context { // {{{ @@ -125,6 +128,7 @@ func (c *Context) Begin(m *Message) *Context { // {{{ } c.Requests = []*Message{m} + c.Historys = []*Message{m} if c.Server != nil { c.Server.Begin(m, m.Meta["detail"]...) @@ -155,44 +159,53 @@ func (c *Context) Start(m *Message) bool { // {{{ } // }}} -func (c *Context) Close(m *Message, arg ...string) { // {{{ - if c.Server == nil || c.Server.Close(m, arg...) { - m.Log("close", c, "%d %v", m.Capi("ncontext", -1)+1, arg) +func (c *Context) Close(m *Message, arg ...string) bool { // {{{ + m.Log("close", c, "close %v", arg) + if m.Target == c { + for k, v := range c.Sessions { + delete(c.Sessions, k) + if v.Target != c && !v.Target.Close(v, arg...) { + return false + } + } + } + + if c.Server != nil && !c.Server.Close(m, arg...) { + return false + } + + if m.Source == c { + if _, ok := c.Sessions[m.Name]; ok { + delete(c.Sessions, m.Name) + m.Target.Server.Close(m, arg...) + } + } else { + if m.Index == -1 { + return true + } + } + + if len(c.Sessions) > 0 { + return false + } + + if m.Cap("status") == "close" { + return true + } + + if c.context != nil && len(c.contexts) == 0 { + m.Log("close", c, "%d context %v", m.root.Capi("ncontext", -1)+1, arg) delete(c.context.contexts, c.Name) } - return - if m.Target == c { - for _, v := range c.Sessions { - if v.Target != c { - v.Target.Close(v, arg...) - } - } - - if c.Server != nil && c.Server.Close(m, arg...) { - if len(c.Sessions) == 0 && c.context != nil { - delete(c.context.contexts, c.Name) - } - } - - for _, v := range c.Requests { - if v.Source != c { - v.Source.Close(v, arg...) - } - } - } else if m.Source == c { - delete(c.Sessions, m.Name) - - if c.Server != nil && c.Server.Close(m, arg...) { - if len(c.Sessions) == 0 && c.context != nil { - delete(c.context.contexts, c.Name) - } + for _, v := range c.Requests { + if v.Source != c && v.Index != -1 { + v.Index = -1 + v.Source.Close(v, arg...) } } - if len(c.Requests) == 0 { - m.Log(m.Cap("status", "stop"), c, "%d %v", m.root.Capi("nserver", -1), m.Meta["detail"]) - } + return true } // }}} @@ -602,6 +615,15 @@ func (m *Message) Reply(key ...string) *Message { // {{{ return msg } +// }}} +func (m *Message) Format() string { // {{{ + name := fmt.Sprintf("%s->%s", m.Source.Name, m.Target.Name) + if m.Name != "" { + name = fmt.Sprintf("%s.%s->%s.%d", m.Source.Name, m.Name, m.Target.Name, m.Index) + } + return fmt.Sprintf("%d(%s): %s %v", m.code, name, m.time.Format("15:04:05"), m.Meta["detail"]) +} + // }}} func (m *Message) BackTrace(hand func(m *Message) bool) { // {{{ @@ -616,6 +638,9 @@ func (m *Message) BackTrace(hand func(m *Message) bool) { // {{{ // }}} func (m *Message) Travel(c *Context, hand func(m *Message) bool) { // {{{ + if c == nil { + c = m.Target + } target := m.Target cs := []*Context{c} @@ -856,10 +881,10 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{ } } - if c.Requests == nil { - c.Requests = make([]*Message, 0, 10) + if c.Historys == nil { + c.Historys = make([]*Message, 0, 10) } - c.Requests = append(c.Requests, m) + c.Historys = append(c.Historys, m) }) return m.Get("result") @@ -902,6 +927,10 @@ func (m *Message) Deal(pre func(msg *Message, arg ...string) bool, post func(msg // }}} func (m *Message) Post(s *Context) string { // {{{ + if s == nil { + s = m.Target.Master + } + m.Assert(s.messages != nil, s.Name+" 没有开启消息处理") if s.messages <- m; m.Wait != nil { @@ -1048,7 +1077,7 @@ func (m *Message) Cap(key string, arg ...string) string { // {{{ // }}} -var Index = &Context{Name: "ctx", Help: "根模块", +var Index = &Context{Name: "ctx", Help: "元始模块", Caches: map[string]*Cache{ "nserver": &Cache{Name: "服务数量", Value: "0", Help: "显示已经启动运行模块的数量"}, "ncontext": &Cache{Name: "模块数量", Value: "0", Help: "显示功能树已经注册模块的数量"}, @@ -1164,68 +1193,67 @@ var Index = &Context{Name: "ctx", Help: "根模块", return "" // }}} }}, - "message": &Command{Name: "message [index|home] [order]", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) string { + "message": &Command{Name: "message code", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) string { switch len(arg) { // {{{ case 0: - for k, v := range m.Target.Sessions { - if v.Name != "" { - m.Echo("%s %s.%s -> %s.%d: %s %v\n", k, v.Source.Name, v.Name, v.Target.Name, v.Index, v.time.Format("15:04:05"), v.Meta["detail"]) - } else { - m.Echo("%s %s -> %s: %s %v\n", k, v.Source.Name, v.Target.Name, v.time.Format("15:04:05"), v.Meta["detail"]) - } - } - + m.Echo("\033[31mrequests:\033[0m\n") for i, v := range m.Target.Requests { - if v.Name != "" { - m.Echo("%d %s.%s -> %s.%d: %s %v\n", i, v.Source.Name, v.Name, v.Target.Name, v.Index, v.time.Format("15:04:05"), v.Meta["detail"]) - } else { - m.Echo("%d %s -> %s: %s %v\n", i, v.Source.Name, v.Target.Name, v.time.Format("15:04:05"), v.Meta["detail"]) - } + m.Echo("%d %s\n", i, v.Format()) for i, v := range v.messages { - if v.Name != "" { - m.Echo(" %d %s.%s -> %s.%d: %s %v\n", i, v.Source.Name, v.Name, v.Target.Name, v.Index, v.time.Format("15:04:05"), v.Meta["detail"]) - } else { - m.Echo(" %d %s -> %s: %s %v\n", i, v.Source.Name, v.Target.Name, v.time.Format("15:04:05"), v.Meta["detail"]) - } + m.Echo(" %d %s\n", i, v.Format()) } } - case 1, 2: + + m.Echo("\033[32msessions:\033[0m\n") + for k, v := range m.Target.Sessions { + m.Echo("%s %s\n", k, v.Format()) + } + + m.Echo("\033[33mhistorys:\033[0m\n") + for i, v := range m.Target.Historys { + m.Echo("%d %s\n", i, v.Format()) + for i, v := range v.messages { + m.Echo(" %d %s\n", i, v.Format()) + } + } + case 1: n, e := strconv.Atoi(arg[0]) - v := m - if e == nil && 0 <= n && n < len(m.Target.Requests) { - v = m.Target.Requests[n] - } else { - v = m.Target.Sessions[arg[0]] - } + m.Assert(e) - if v != nil { - if len(arg) > 1 { - if n, e = strconv.Atoi(arg[1]); e == nil && 0 <= n && n < len(v.messages) { - v = v.messages[n] + ms := []*Message{m.root} + for i := 0; i < len(ms); i++ { + if ms[i].code == n { + if ms[i].message != nil { + m.Echo("message: %d\n", ms[i].message.code) } - } - if v.Name != "" { - m.Echo("%s.%s -> %s.%d: %s %v\n", v.Source.Name, v.Name, v.Target.Name, v.Index, v.time.Format("15:04:05"), v.Meta["detail"]) - } else { - m.Echo("%s -> %s: %s %v\n", v.Source.Name, v.Target.Name, v.time.Format("15:04:05"), v.Meta["detail"]) - } + m.Echo("%s\n", ms[i].Format()) + if len(ms[i].Meta["option"]) > 0 { + m.Echo("option: %v\n", ms[i].Meta["option"]) + } + for _, k := range ms[i].Meta["option"] { + m.Echo(" %s: %v\n", k, ms[i].Meta[k]) + } - if len(v.Meta["option"]) > 0 { - m.Echo("option:\n") - } - for _, k := range v.Meta["option"] { - m.Echo(" %s: %v\n", k, v.Meta[k]) - } - if len(v.Meta["result"]) > 0 { - m.Echo("result: %v\n", v.Meta["result"]) - } - if len(v.Meta["append"]) > 0 { - m.Echo("append:\n") - } - for _, k := range v.Meta["append"] { - m.Echo(" %s: %v\n", k, v.Meta[k]) + if len(ms[i].Meta["result"]) > 0 { + m.Echo("result: %v\n", ms[i].Meta["result"]) + } + if len(ms[i].Meta["append"]) > 0 { + m.Echo("append: %v\n", ms[i].Meta["append"]) + } + for _, k := range ms[i].Meta["append"] { + m.Echo(" %s: %v\n", k, ms[i].Meta[k]) + } + + if len(ms[i].messages) > 0 { + m.Echo("messages: %d\n", len(ms[i].messages)) + } + for _, v := range ms[i].messages { + m.Echo(" %s\n", v.Format()) + } + break } + ms = append(ms, ms[i].messages...) } } @@ -1319,7 +1347,7 @@ var Index = &Context{Name: "ctx", Help: "根模块", m.Echo("%s\n", target.Help) return true }) - case len(arg) > 0: + case len(arg) > 0 && v != m: v.Set("detail", arg...).Cmd() } } @@ -1511,7 +1539,7 @@ var Index = &Context{Name: "ctx", Help: "根模块", return all }) case 2: - m.Conf(arg[0], arg[1]) + m.Cap(arg[0], arg[1]) case 4: m.Cap(arg[0], arg[1:]...) } @@ -1559,13 +1587,13 @@ func Start(args ...string) { log.Println("\n\n") Index.Group = "root" - Index.Owner = Index.contexts["aaa"] Index.Master = Index.contexts["cli"] for _, m := range Pulse.Search("") { m.Target.root = Index m.Target.Begin(m) } + Index.Requests = append(Index.Requests, Pulse) log.Println() for _, m := range Pulse.Search(Pulse.Conf("start")) { diff --git a/src/context/mdb/mdb.go b/src/context/mdb/mdb.go index 0b50ca8f..be0de87d 100644 --- a/src/context/mdb/mdb.go +++ b/src/context/mdb/mdb.go @@ -59,19 +59,27 @@ func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { // {{{ - if mdb.DB != nil && m.Target == mdb.Context { + if mdb.Context == Index { + return false + } + + switch mdb.Context { + case m.Target: + case m.Source: + } + + if mdb.DB != nil { m.Log("info", nil, "%d close %s %s", m.Capi("nsource", -1)+1, m.Cap("driver"), m.Cap("source")) mdb.DB.Close() mdb.DB = nil - return true } - return false + return true } // }}} -var Index = &ctx.Context{Name: "mdb", Help: "内存数据库", +var Index = &ctx.Context{Name: "mdb", Help: "数据中心", Caches: map[string]*ctx.Cache{ "nsource": &ctx.Cache{Name: "数据源数量", Value: "0", Help: "已打开数据库的数量"}, }, @@ -83,7 +91,7 @@ var Index = &ctx.Context{Name: "mdb", Help: "内存数据库", m.Assert(len(arg) > 2, "缺少参数") // {{{ m.Master, m.Target = c, c m.Cap("stream", m.Cap("nsource")) - m.Start(arg[0], arg[1], arg[2:]...) + m.Start(arg[0], "数据存储", arg[2:]...) return "" // }}} }}, diff --git a/src/context/tcp/tcp.go b/src/context/tcp/tcp.go index 3fc6855c..8f0912b6 100644 --- a/src/context/tcp/tcp.go +++ b/src/context/tcp/tcp.go @@ -20,14 +20,10 @@ func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server c.Caches = map[string]*ctx.Cache{ "protocol": &ctx.Cache{Name: "protocol(tcp/tcp4/tcp6)", Value: m.Conf("protocol"), Help: "监听地址"}, "security": &ctx.Cache{Name: "security(true/false)", Value: m.Conf("security"), Help: "加密通信"}, - "address": &ctx.Cache{Name: "address", Value: arg[1], Help: "监听地址"}, + "address": &ctx.Cache{Name: "address", Value: "", Help: "监听地址"}, } c.Configs = map[string]*ctx.Config{} - if len(arg) > 2 { - m.Cap("security", arg[2]) - } - s := new(TCP) s.Context = c return s @@ -36,53 +32,65 @@ func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server // }}} func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ + if m.Target == Index { + Pulse = m + } + return tcp } // }}} func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ + if len(arg) > 1 { + m.Cap("address", arg[1]) + } + if len(arg) > 2 { + m.Cap("security", arg[2]) + } + switch arg[0] { case "dial": c, e := net.Dial(m.Cap("protocol"), m.Cap("address")) m.Assert(e) tcp.Conn = c + m.Log("info", nil, "dial(%d) %v->%v", m.Capi("nclient", 1), tcp.LocalAddr(), tcp.RemoteAddr()) + m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr())) - m.Log("info", nil, "dial(%d) %v->%v", m.Capi("nclient"), c.LocalAddr(), c.RemoteAddr()) // m.Reply(c.LocalAddr().String()).Put("option", "io", c).Cmd("open") return false case "accept": + c, e := m.Data["io"].(net.Conn) + m.Assert(e) + tcp.Conn = c + m.Log("info", nil, "accept(%d) %v<-%v", m.Capi("nclient", 1), tcp.LocalAddr(), tcp.RemoteAddr()) + m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr())) + + s, e := m.Data["source"].(*ctx.Context) + m.Assert(e) + msg := m.Spawn(s).Put("option", "io", c) + msg.Cmd("open") + msg.Cap("stream", tcp.RemoteAddr().String()) + + if tcp.Sessions == nil { + tcp.Sessions = make(map[string]*ctx.Message) + } + tcp.Sessions["open"] = msg + msg.Name = "open" + + // m.Reply(c.RemoteAddr().String()) return false } l, e := net.Listen(m.Cap("protocol"), m.Cap("address")) m.Assert(e) tcp.Listener = l - - m.Log("info", nil, "listen(%d) %v", m.Capi("nlisten"), l.Addr()) + m.Log("info", nil, "listen(%d) %v", m.Capi("nlisten", 1), l.Addr()) + m.Cap("stream", fmt.Sprintf("%s", l.Addr())) for { c, e := l.Accept() m.Assert(e) - - s, i := m.Target, 0 - m.BackTrace(func(m *ctx.Message) bool { - s = m.Target - if i++; i == 2 { - return false - } - return true - }) - - msg := m.Spawn(s) - msg.Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), c.RemoteAddr().String(), "accept", c.RemoteAddr().String()) - msg.Log("info", nil, "accept(%d) %v<-%v", m.Capi("nclient"), c.LocalAddr(), c.RemoteAddr()) - - if tcp, ok := msg.Target.Server.(*TCP); ok { - tcp.Conn = c - } - rep := m.Reply(c.RemoteAddr().String()) - rep.Source = msg.Target - rep.Put("option", "io", c).Cmd("open") + m.Spawn(Index).Put("option", "io", c).Put("option", "source", m.Source).Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), "网络连接", "accept", c.RemoteAddr().String()) } return true @@ -90,22 +98,33 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool { // {{{ - if tcp.Listener != nil { - m.Log("info", nil, "close(%d) %v", m.Capi("nlisten", -1)+1, tcp.Listener.Addr()) - tcp.Listener.Close() - return true - } - if tcp.Conn != nil { - tcp.Conn.Close() - return true + if tcp.Context == Index { + return false } - return false + switch tcp.Context { + case m.Target: + case m.Source: + if tcp.Listener != nil { + return false + } + + } + + if tcp.Listener != nil { + m.Log("info", nil, "close(%d) %v", Pulse.Capi("nlisten", -1)+1, tcp.Listener.Addr()) + tcp.Listener.Close() + } + if tcp.Conn != nil { + m.Log("info", nil, "close %v", tcp.Conn.LocalAddr()) + tcp.Conn.Close() + } + return true } // }}} -var Index = &ctx.Context{Name: "tcp", Help: "网络连接", +var Index = &ctx.Context{Name: "tcp", Help: "网络中心", Caches: map[string]*ctx.Cache{ "nlisten": &ctx.Cache{Name: "nlisten", Value: "0", Help: "监听数量"}, "nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"}, @@ -118,14 +137,14 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", "listen": &ctx.Command{Name: "listen [address [security]]", Help: "监听连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { switch len(arg) { // {{{ case 0: - m.Travel(m.Target, func(m *ctx.Message) bool { + m.Travel(nil, func(m *ctx.Message) bool { if tcp, ok := m.Target.Server.(*TCP); ok && tcp.Listener != nil { m.Echo("%s %v\n", m.Target.Name, tcp.Addr()) } return true }) default: - m.Start(fmt.Sprintf("pub%d", m.Capi("nlisten", 1)), arg[0], m.Meta["detail"]...) + m.Start(fmt.Sprintf("pub%d", m.Capi("nlisten")+1), "网络监听", m.Meta["detail"]...) } return "" // }}} @@ -133,14 +152,14 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", "dial": &ctx.Command{Name: "dial [address [security]]", Help: "建立连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { switch len(arg) { // {{{ case 0: - m.Travel(m.Target, func(m *ctx.Message) bool { + m.Travel(nil, func(m *ctx.Message) bool { if tcp, ok := m.Target.Server.(*TCP); ok && tcp.Conn != nil { m.Echo("%s %v<->%v\n", m.Target.Name, tcp.LocalAddr(), tcp.RemoteAddr()) } return true }) default: - m.Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), arg[0], m.Meta["detail"]...) + m.Start(fmt.Sprintf("com%d", m.Capi("nclient")+1), "网络连接", m.Meta["detail"]...) } return "" // }}} @@ -153,9 +172,9 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", // }}} }}, "recv": &ctx.Command{Name: "recv size", Help: "接收消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + size, e := strconv.Atoi(arg[0]) + m.Assert(e) if tcp, ok := m.Target.Server.(*TCP); ok && tcp.Conn != nil { // {{{ - size, e := strconv.Atoi(arg[0]) - m.Assert(e) buf := make([]byte, size) tcp.Conn.Read(buf) return string(buf) @@ -174,6 +193,8 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", }, } +var Pulse *ctx.Message + func init() { tcp := &TCP{} tcp.Context = Index diff --git a/src/context/web/web.go b/src/context/web/web.go index 4bdfe1b0..21de3270 100644 --- a/src/context/web/web.go +++ b/src/context/web/web.go @@ -117,7 +117,6 @@ func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ web.Caches["route"] = &ctx.Cache{Name: "route", Value: "/" + web.Context.Name + "/", Help: "请求路径"} web.Caches["register"] = &ctx.Cache{Name: "已初始化(yes/no)", Value: "no", Help: "模块是否已注册"} web.Caches["master"] = &ctx.Cache{Name: "master(yes/no)", Value: "no", Help: "日志输出请求头"} - m.Cap("stream", m.Cap("route")+" -> "+m.Cap("directory")) web.ServeMux = http.NewServeMux() if mux, ok := m.Target.Server.(MUX); ok { @@ -166,7 +165,7 @@ func (web *WEB) Start(m *ctx.Message, arg ...string) bool { // {{{ return true }) - web.Caches["address"] = &ctx.Cache{Name: "address", Value: ":9393", Help: "监听地址"} + web.Caches["address"] = &ctx.Cache{Name: "address", Value: ":9191", Help: "监听地址"} web.Caches["protocol"] = &ctx.Cache{Name: "protocol", Value: "http", Help: "服务协议"} if len(arg) > 1 { m.Cap("address", arg[1]) diff --git a/src/example/bench.go b/src/example/bench.go index 757c011c..e8f8ee84 100644 --- a/src/example/bench.go +++ b/src/example/bench.go @@ -2,16 +2,15 @@ package main import ( "context" + _ "context/aaa" _ "context/cli" _ "context/mdb" _ "context/tcp" - - _ "context/aaa" - _ "context/ssh" - _ "context/web" + _ "context/ssh" + _ "context/lex" "os"