1
0
forked from x/ContextOS

mac pro code 整理了代码,串联cli和tcp建立远程连接

This commit is contained in:
shaoying 2017-11-03 08:51:38 +08:00
parent 2f03c83978
commit ff2d9a1a62
6 changed files with 528 additions and 362 deletions

112
etc/go.snippets Normal file
View File

@ -0,0 +1,112 @@
snippet p
package ${1:main}
${2}
snippet i
import (
"${1}"
)
${2}
snippet t
type ${1} struct {
${2}
}
${3}
snippet ti
type ${1} interface {
${2}
}
${3}
snippet c
package `Filename()`
import (
"context"
)
type `toupper(substitute(expand("%:t"), ".go", "", ""))` struct {
*ctx.Context
*ctx.CTX
}
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Begin() bool {
return true
}
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Start() bool {
return true
}
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Spawn(c *ctx.Context, arg ...string) ctx.Server {
c.Caches = map[string]*ctx.Cache{}
c.Configs = map[string]*ctx.Config{}
c.Commands = map[string]*ctx.Command{}
s := new(`toupper(substitute(expand("%:t"), ".go", "", ""))`)
s.CTX = ctx.Ctx
s.Context = c
return s
}
var Index = &ctx.Context{Name: "`Filename()`", Help: "${1}",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{},
Commands: map[string]*ctx.Command{},
}
func init() {
`Filename()` := &`toupper(substitute(expand("%:t"), ".go", "", ""))`{}
`Filename()`.CTX = ctx.Ctx
`Filename()`.Context = Index
ctx.Index.Register(Index, `Filename()`)
}
snippet v
var (
${1}
)
${2}
snippet m
func main() {
${1}
}
snippet h
func(w http.ResponseWriter, r *http.Request) {
${1}
})
snippet f
func${1}(${2}) ${3}{
${4}
}${5}
snippet "
"${1}"${2}
snippet `
`${1}`${2}
snippet (
(${1})${2}
snippet [
[${1}]${2}
snippet {
{${1}}${2}
snippet if
if ${1} {
${2}
}
${3}
snippet for
for ${1}{
${2}
}
${3}
snippet switch
switch ${1}{
case ${2}:
${3}
}
${4}
snippet select
select {
case ${1}:
${2}
}
${3}

View File

@ -5,5 +5,4 @@ alias $ cache
alias & server alias & server
alias * message alias * message
~root remote slave listen :9393 tcp
~tcp

View File

@ -18,11 +18,11 @@ import ( // {{{
// }}} // }}}
type CLI struct { type CLI struct {
in *os.File out io.WriteCloser
ins []*os.File in io.ReadCloser
ins []io.ReadCloser
bio *bufio.Reader bio *bufio.Reader
bios []*bufio.Reader bios []*bufio.Reader
out *os.File
history []map[string]string history []map[string]string
alias map[string]string alias map[string]string
@ -31,11 +31,12 @@ type CLI struct {
target *ctx.Context target *ctx.Context
*ctx.Context *ctx.Context
*ctx.CTX
} }
func (cli *CLI) push(f *os.File) { // {{{ func (cli *CLI) push(f io.ReadCloser) { // {{{
if cli.ins == nil || cli.bios == nil { if cli.ins == nil || cli.bios == nil {
cli.ins = make([]*os.File, 0, 3) cli.ins = make([]io.ReadCloser, 0, 3)
cli.bios = make([]*bufio.Reader, 0, 3) cli.bios = make([]*bufio.Reader, 0, 3)
} }
@ -47,7 +48,7 @@ func (cli *CLI) push(f *os.File) { // {{{
// }}} // }}}
func (cli *CLI) parse() bool { // {{{ func (cli *CLI) parse() bool { // {{{
if len(cli.ins) == 1 { if len(cli.ins) == 1 || cli.Conf("slient") != "yes" {
cli.echo(cli.Conf("PS1")) cli.echo(cli.Conf("PS1"))
} }
@ -63,8 +64,6 @@ func (cli *CLI) parse() bool { // {{{
} }
cli.echo("\n") cli.echo("\n")
cli.exit <- true cli.exit <- true
return false
} else { } 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]
@ -75,24 +74,24 @@ func (cli *CLI) parse() bool { // {{{
} }
cli.Check(e) cli.Check(e)
line = l line = l
if len(cli.ins) > 1 || cli.Conf("slient") != "yes" {
cli.echo(line)
}
if len(line) == 1 {
return true
}
} else { } else {
line = cli.next line = cli.next
if len(cli.ins) == 1 { cli.next = ""
if cli.Conf("slient") != "yes" {
cli.echo(line) cli.echo(line)
cli.echo("\n") cli.echo("\n")
} }
} }
if len(cli.ins) > 1 {
cli.echo(cli.Conf("PS1"))
cli.echo(line)
}
cli.next = ""
if len(line) == 1 {
return true
}
line = strings.TrimSpace(line) line = strings.TrimSpace(line)
if line[0] == '#' { if line[0] == '#' {
return true return true
@ -142,34 +141,33 @@ func (cli *CLI) parse() bool { // {{{
func (cli *CLI) deal(msg *ctx.Message) bool { // {{{ func (cli *CLI) deal(msg *ctx.Message) bool { // {{{
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
msg.Echo("%s", e) msg.Echo("%s\n", e)
debug.PrintStack() debug.PrintStack()
log.Println(e) log.Println(e)
msg.End(false)
} }
}() }()
detail := msg.Meta["detail"] detail := msg.Meta["detail"]
switch cli.Conf("mode") { if a, ok := cli.alias[detail[0]]; ok {
case "local": detail[0] = a
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 := cli.target.Commands[detail[0]]; ok {
cli.target.Message = msg
cli.next = cli.target.Cmd(msg, detail...)
} else {
cmd := exec.Command(detail[0], detail[1:]...)
v, e := cmd.CombinedOutput()
if e != nil {
msg.Echo("%s\n", e)
}
msg.Echo(string(v))
log.Println(cli.Name, "command:", detail)
}
} }
if _, ok := cli.Commands[detail[0]]; ok {
cli.next = cli.Cmd(msg, detail...)
} else if _, ok := cli.target.Commands[detail[0]]; ok {
cli.next = cli.target.Cmd(msg, detail...)
} else {
cmd := exec.Command(detail[0], detail[1:]...)
v, e := cmd.CombinedOutput()
if e != nil {
msg.Echo("%s\n", e)
}
msg.Echo(string(v))
log.Println(cli.Name, "command:", detail)
}
msg.End(true)
cli.history = append(cli.history, map[string]string{ cli.history = append(cli.history, map[string]string{
"time": time.Now().Format("15:04:05"), "time": time.Now().Format("15:04:05"),
"index": fmt.Sprintf("%d", len(cli.history)), "index": fmt.Sprintf("%d", len(cli.history)),
@ -188,34 +186,39 @@ func (cli *CLI) echo(str string, arg ...interface{}) { // {{{
// }}} // }}}
func (cli *CLI) Begin() bool { // {{{ func (cli *CLI) Begin() bool { // {{{
cli.history = make([]map[string]string, 0, 100)
cli.alias = make(map[string]string, 10)
cli.exit = make(chan bool)
cli.target = cli.Context
if f, e := os.Open(cli.Conf("init.sh")); e == nil { if f, e := os.Open(cli.Conf("init.sh")); e == nil {
cli.push(f) cli.push(f)
} }
cli.history = make([]map[string]string, 0, 100)
cli.alias = make(map[string]string, 10)
cli.exit = make(chan bool)
cli.target = cli.Context
return true
}
// }}}
func (cli *CLI) Start() bool { // {{{
if msg, ok := cli.Session["remote"]; ok {
cli.push(msg.Data["result"].(io.ReadCloser))
cli.out = msg.Data["result"].(io.WriteCloser)
cli.echo(cli.Conf("开场白"))
}
if cli.Conf("slient") != "yes" { if cli.Conf("slient") != "yes" {
cli.echo("\n") cli.echo("\n")
cli.echo(cli.Conf("开场白")) cli.echo(cli.Conf("开场白"))
cli.echo("\n") cli.echo("\n")
} }
return true if cli.Conf("mode") == "local" {
} go func() {
defer recover()
for cli.parse() {
}
}()
}
// }}} for cli.deal(cli.Get()) {
func (cli *CLI) Start() bool { // {{{
go func() {
for cli.parse() {
}
}()
for {
msg := cli.Get()
msg.End(cli.deal(msg))
} }
return true return true
@ -223,6 +226,12 @@ func (cli *CLI) Start() bool { // {{{
// }}} // }}}
func (cli *CLI) Spawn(c *ctx.Context, arg ...string) ctx.Server { // {{{ func (cli *CLI) Spawn(c *ctx.Context, arg ...string) ctx.Server { // {{{
c.Caches = map[string]*ctx.Cache{}
c.Configs = map[string]*ctx.Config{
"address": &ctx.Config{Name: "address", Value: arg[0], Help: "监听地址"},
"protocol": &ctx.Config{Name: "protocol", Value: arg[1], Help: "监听协议"},
}
s := new(CLI) s := new(CLI)
s.Context = c s.Context = c
return s return s
@ -240,12 +249,10 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
cli := c.Server.(*CLI) // {{{ cli := c.Server.(*CLI) // {{{
cli.out = os.Stdout cli.out = os.Stdout
cli.push(os.Stdin) cli.push(os.Stdin)
return arg return arg
// }}} // }}}
}}, }},
"slient": &ctx.Config{Name: "slient", Value: "yes", Help: "静默启动"}, "slient": &ctx.Config{Name: "slient", Value: "yes", Help: "静默启动"},
"init.sh": &ctx.Config{Name: "init.sh", Value: "etc/hi.sh", Help: "启动脚本"},
"PS1": &ctx.Config{Name: "PS1", Value: "etcvpn>", Help: "命令行提示符", Hand: func(c *ctx.Context, arg string) string { "PS1": &ctx.Config{Name: "PS1", Value: "etcvpn>", Help: "命令行提示符", Hand: func(c *ctx.Context, arg string) string {
cli := c.Server.(*CLI) // {{{ cli := c.Server.(*CLI) // {{{
if cli != nil && cli.target != nil { if cli != nil && cli.target != nil {
@ -256,95 +263,130 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
}}, }},
}, },
Commands: map[string]*ctx.Command{ Commands: map[string]*ctx.Command{
"cache": &ctx.Command{"cache [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { "context": &ctx.Command{"context [spawn|find|search name [which]]|root|back|home", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
cli := c.Server.(*CLI) // {{{ cli, ok := c.Server.(*CLI) // {{{
switch len(arg) { switch len(arg) {
case 1: case 1:
for k, v := range cli.target.Caches { cs := []*ctx.Context{msg.Target}
msg.Echo("%s(%s): %s\n", k, v.Value, v.Help) for i := 0; i < len(cs); i++ {
if len(cs[i].Contexts) > 0 {
msg.Echo("%s: ", cs[i].Name)
for k, v := range cs[i].Contexts {
cs = append(cs, v)
msg.Echo("%s, ", k)
}
msg.Echo("\n")
}
} }
case 2: case 2:
if v, ok := cli.target.Caches[arg[1]]; ok {
msg.Echo("%s: %s\n", v.Name, v.Help)
}
case 3:
switch arg[1] { switch arg[1] {
case "delete": case "root":
if _, ok := cli.target.Caches[arg[2]]; ok { if ok {
delete(cli.target.Caches, arg[2]) cli.target = cli.Context.Root
} else {
msg.Target = msg.Target.Root
}
case "back":
if ok {
if cli.Context.Context != nil {
cli.target = cli.Context.Context
}
} else {
if msg.Target.Context != nil {
msg.Target = msg.Target.Context
}
}
case "home":
if ok {
cli.target = cli.Context
} else {
msg.Target = msg.Context
} }
default: default:
if _, ok := cli.target.Caches[arg[1]]; ok { if cs := msg.Target.Find(strings.Split(arg[1], ".")); cs != nil {
msg.Echo("%s: %s\n", arg[1], cli.target.Cap(arg[1:]...)) if ok {
cli.target = cs
} else {
msg.Target = cs
}
} }
} }
case 5: case 3, 4:
cli.target.Cap(arg[1:]...) switch arg[1] {
case "spawn":
msg.Target.Spawn(arg[2])
case "find":
cs := msg.Target.Find(strings.Split(arg[2], "."))
if cs != nil {
msg.Echo("%s: %s\n", cs.Name, cs.Help)
if len(arg) == 4 {
if ok {
cli.target = cs
} else {
msg.Target = cs
}
}
}
case "search":
cs := msg.Target.Search(arg[2])
for i, v := range cs {
msg.Echo("[%d] %s: %s\n", i, v.Name, v.Help)
}
if len(arg) == 4 {
n, e := strconv.Atoi(arg[3])
if 0 <= n && n < len(cs) && e == nil {
if ok {
cli.target = cs[n]
} else {
msg.Target = cs[n]
}
} else {
msg.Echo("参数错误(0<=n<%s)", len(cs))
}
}
}
}
return ""
// }}}
}},
"message": &ctx.Command{"message detail...", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
msg.Meta["detail"] = arg[1:] // {{{
if c == msg.Target {
go msg.Target.Post(msg)
} else {
msg.Target.Post(msg)
} }
return "" return ""
// }}} // }}}
}}, }},
"config": &ctx.Command{"config [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { "server": &ctx.Command{"server start|stop|switch", "服务启动停止切换", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
cli := c.Server.(*CLI) // {{{ s := msg.Target // {{{
switch len(arg) { switch len(arg) {
case 1: case 1:
for k, v := range cli.target.Configs { return "server start"
msg.Echo("%s(%s): %s\n", k, v.Value, v.Help)
}
case 2: case 2:
if v, ok := cli.target.Configs[arg[1]]; ok {
msg.Echo("%s: %s\n", v.Name, v.Help)
}
case 3:
switch arg[1] { switch arg[1] {
case "delete": case "start":
if _, ok := cli.target.Configs[arg[2]]; ok { if s != nil {
delete(cli.target.Configs, arg[2]) go s.Start()
}
default:
if _, ok := cli.target.Configs[arg[1]]; ok {
cli.target.Conf(arg[1:]...)
}
}
case 5:
cli.target.Conf(arg[1:]...)
}
return ""
// }}}
}},
"command": &ctx.Command{"command [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
cli := c.Server.(*CLI) // {{{
switch len(arg) {
case 1:
for k, v := range cli.target.Commands {
msg.Echo("%s: %s\n", k, v.Help)
}
case 2:
if v, ok := cli.target.Commands[arg[1]]; ok {
msg.Echo("%s: %s\n", v.Name, v.Help)
}
case 3:
switch arg[1] {
case "delete":
if _, ok := cli.target.Commands[arg[2]]; ok {
delete(cli.target.Commands, arg[2])
} }
case "stop":
case "switch":
} }
} }
msg.Echo("\n")
return "" return ""
// }}} // }}}
}}, }},
"source": &ctx.Command{"source file", "运行脚本", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { "source": &ctx.Command{"source file", "运行脚本", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
cli := c.Server.(*CLI) // {{{ cli := c.Server.(*CLI) // {{{
switch len(arg) {
f, e := os.Open(arg[1]) case 2:
c.Check(e) f, e := os.Open(arg[1])
cli.push(f) c.Check(e)
cli.push(f)
}
return "" return ""
// }}} // }}}
@ -384,101 +426,118 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
return "" return ""
// }}} // }}}
}}, }},
"message": &ctx.Command{"message detail...", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { "command": &ctx.Command{"command [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
msg.Meta["detail"] = arg[1:] switch len(arg) { // {{{
msg.Target.Post(msg)
return ""
}},
"server": &ctx.Command{"server start|stop|switch", "服务启动停止切换", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
s := msg.Target // {{{
switch len(arg) {
case 1: case 1:
return "server start" for k, v := range msg.Target.Commands {
msg.Echo("%s: %s\n", k, v.Help)
}
case 2: case 2:
if v, ok := msg.Target.Commands[arg[1]]; ok {
msg.Echo("%s: %s\n", v.Name, v.Help)
}
case 3:
switch arg[1] { switch arg[1] {
case "start": case "delete":
go s.Start() if _, ok := msg.Target.Commands[arg[2]]; ok {
case "stop": delete(msg.Target.Commands, arg[2])
case "switch": }
} }
} }
msg.Echo("\n")
return "" return ""
// }}} // }}}
}}, }},
"context": &ctx.Command{"context [spawn|fork|find|search name [switch]]|root|back|home", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { "config": &ctx.Command{"config [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
cli := c.Server.(*CLI) // {{{ switch len(arg) { // {{{
switch len(arg) {
case 1: case 1:
cs := []*ctx.Context{cli.target} for k, v := range msg.Target.Configs {
for i := 0; i < len(cs); i++ { msg.Echo("%s(%s): %s\n", k, v.Value, v.Help)
if len(cs[i].Contexts) > 0 {
msg.Echo("%s: ", cs[i].Name)
for k, v := range cs[i].Contexts {
cs = append(cs, v)
msg.Echo("%s, ", k)
}
msg.Echo("\n")
}
} }
case 2, 3, 4, 5: case 2:
if v, ok := msg.Target.Configs[arg[1]]; ok {
msg.Echo("%s: %s\n", v.Name, v.Help)
}
case 3:
switch arg[1] { switch arg[1] {
case "spawn": case "delete":
msg.Target.Spawn(arg[2]) if _, ok := msg.Target.Configs[arg[2]]; ok {
case "root": delete(msg.Target.Configs, arg[2])
cli.target = cli.Context.Root
case "back":
if cli.Context.Context != nil {
cli.target = cli.Context.Context
}
case "home":
cli.target = cli.Context
case "find":
cs := c.Root.Find(strings.Split(arg[2], "."))
if cs != nil {
msg.Echo("%s: %s\n", cs.Name, cs.Help)
if len(arg) == 4 {
cli.target = cs
}
}
case "search":
cs := c.Root.Search(arg[2])
for i, v := range cs {
msg.Echo("[%d] %s: %s\n", i, v.Name, v.Help)
}
if len(arg) == 5 {
n, e := strconv.Atoi(arg[4])
if 0 <= n && n < len(cs) && e == nil {
cli.target = cs[0]
} else {
msg.Echo("参数错误(0<=n<%s)", len(cs))
}
}
if len(arg) == 4 {
cli.target = cs[0]
} }
default: default:
cs := c.Root.Find(strings.Split(arg[1], ".")) if _, ok := msg.Target.Configs[arg[1]]; ok {
if cs != nil { msg.Target.Conf(arg[1:]...)
msg.Echo("%s: %s\n", cs.Name, cs.Help) }
if cs != nil { }
cli.target = cs case 5:
} msg.Target.Conf(arg[1:]...)
}
return ""
// }}}
}},
"cache": &ctx.Command{"cache [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
switch len(arg) { // {{{
case 1:
for k, v := range msg.Target.Caches {
msg.Echo("%s(%s): %s\n", k, v.Value, v.Help)
}
case 2:
if v, ok := msg.Target.Caches[arg[1]]; ok {
msg.Echo("%s: %s\n", v.Name, v.Help)
}
case 3:
switch arg[1] {
case "delete":
if _, ok := msg.Target.Caches[arg[2]]; ok {
delete(msg.Target.Caches, arg[2])
}
default:
if _, ok := msg.Target.Caches[arg[1]]; ok {
msg.Echo("%s: %s\n", arg[1], msg.Target.Cap(arg[1:]...))
}
}
case 5:
msg.Target.Cap(arg[1:]...)
}
return ""
// }}}
}},
"remote": &ctx.Command{"remote master|slave listen|dial address protocol", "建立远程连接", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
switch len(arg) {
case 1:
case 5:
if arg[1] == "master" {
if arg[2] == "dial" {
} else {
}
} else {
if arg[2] == "listen" {
msg := &ctx.Message{Code: c.Root.Capi("nmessage", 1), Time: time.Now()}
msg.Add("mode", "local")
msg.Target = c.Root.Find(strings.Split(arg[4], "."))
msg.Context = m.Context
msg.Target.Cmd(msg, "listen", arg[3])
} else {
} }
} }
} }
return "" return ""
// }}} }},
"accept": &ctx.Command{"accept address protocl", "建立远程连接", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
s := msg.Context.Spawn(arg[1], arg[2])
s.Session = make(map[string]*ctx.Message)
s.Session["remote"] = msg
s.Start()
return ""
}}, }},
}, },
Messages: make(chan *ctx.Message, 10), Messages: make(chan *ctx.Message, 10),
} }
func init() { func init() {
self := &CLI{} cli := &CLI{}
self.Context = Index cli.CTX = ctx.Ctx
ctx.Index.Register(Index, self) cli.Context = Index
ctx.Index.Register(Index, cli)
} }

View File

@ -38,18 +38,18 @@ type Command struct { // {{{
// }}} // }}}
type Message struct { // {{{ type Message struct { // {{{
Code int
Time time.Time Time time.Time
Code int
Meta map[string][]string Meta map[string][]string
Data map[string]interface{} Data map[string]interface{}
Wait chan bool Wait chan bool
Index int
Target *Context
Name string Name string
*Context *Context
Target *Context
Index int
} }
func (m *Message) Add(key string, value ...string) string { // {{{ func (m *Message) Add(key string, value ...string) string { // {{{
@ -109,7 +109,6 @@ func (m *Message) Echo(str string, arg ...interface{}) string { // {{{
// }}} // }}}
func (m *Message) End(s bool) { // {{{ func (m *Message) End(s bool) { // {{{
// log.Println(m.Name, "end", m.Code, ":", m.Meta["detail"])
if m.Wait != nil { if m.Wait != nil {
m.Wait <- s m.Wait <- s
} }
@ -132,19 +131,20 @@ type Context struct { // {{{
Caches map[string]*Cache Caches map[string]*Cache
Configs map[string]*Config Configs map[string]*Config
Commands map[string]*Command Commands map[string]*Command
Messages chan *Message Messages chan *Message
Message *Message Message *Message
Server Server
Root *Context Resource []*Message
Context *Context Session map[string]*Message
Contexts map[string]*Context
Index map[string]*Context Index map[string]*Context
Shadows map[string]*Context Shadows map[string]*Context
Session map[string]*Message Contexts map[string]*Context
Resource []*Message Context *Context
Root *Context
} }
func (c *Context) Check(e error) bool { // {{{ func (c *Context) Check(e error) bool { // {{{
@ -159,33 +159,105 @@ func (c *Context) Check(e error) bool { // {{{
} }
// }}} // }}}
func (c *Context) Register(s *Context, self Server) bool { // {{{
func (c *Context) Request(arg ...string) bool { // {{{ if c.Contexts == nil {
if c.Session == nil { c.Contexts = make(map[string]*Context)
c.Session = make(map[string]*Message)
} }
m := &Message{ if x, ok := c.Contexts[s.Name]; ok {
Code: c.Capi("nmessage", 1), panic(errors.New(c.Name + " 上下文已存在" + x.Name))
Time: time.Now(),
Meta: map[string][]string{},
Data: map[string]interface{}{},
Name: arg[0],
} }
m.Context = c
c.Contexts[s.Name] = s
s.Context = c
s.Root = c.Root
s.Server = self
log.Println(c.Name, "register:", s.Name)
return true return true
} }
// }}} // }}}
func (c *Context) Release(key string) bool { // {{{ func (c *Context) Init(arg ...string) { // {{{
if c.Root != nil {
return
}
return true root := c
for root.Context != nil {
root = root.Context
}
if len(arg) > 0 {
root.Conf("bench.log", arg[0])
} else {
root.Conf("bench.log", root.Conf("bench.log"))
}
if len(arg) > 1 {
root.Conf("init.sh", arg[1])
} else {
root.Conf("init.sh", root.Conf("init.sh"))
}
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)
}
}
if len(arg) > 2 {
for _, v := range arg[2:] {
cs = root.Search(v)
for _, s := range cs {
go s.Start()
}
}
} else {
go root.Find(strings.Split(root.Conf("default"), ".")).Start()
}
<-make(chan bool)
} }
// }}} // }}}
func (c *Context) Destroy(index int) bool { // {{{ func (c *Context) Find(name []string) *Context { // {{{
if x, ok := c.Contexts[name[0]]; ok {
log.Println(c.Name, "find:", x.Name)
if len(name) == 1 {
return x
}
return x.Find(name[1:])
}
return true log.Println(c.Name, "not find:", name[0])
return nil
}
// }}}
func (c *Context) Search(name string) []*Context { // {{{
ps := make([]*Context, 0, 3)
cs := []*Context{c}
for i := 0; i < len(cs); i++ {
for _, v := range cs[i].Contexts {
cs = append(cs, v)
}
if strings.Contains(cs[i].Name, name) || strings.Contains(cs[i].Help, name) {
ps = append(ps, cs[i])
log.Println(c.Name, "search:", i, cs[i].Name, "[match]")
} else {
log.Println(c.Name, "search:", i, cs[i].Name)
}
}
return ps
} }
// }}} // }}}
@ -354,125 +426,40 @@ func (c *Context) Del(arg ...string) { // {{{
// }}} // }}}
func (c *Context) Find(name []string) *Context { // {{{ func (c *Context) Request(s *Context, key string) *Message { // {{{
if x, ok := c.Contexts[name[0]]; ok { if c.Session == nil {
log.Println(c.Name, "find:", x.Name) c.Session = make(map[string]*Message)
if len(name) == 1 { }
return x if s.Resource == nil {
} s.Resource = make([]*Message, 0, c.Confi("MessageListSize"))
return x.Find(name[1:])
} }
log.Println(c.Name, "not find:", name[0]) m := &Message{Index: len(s.Resource), Name: key}
return nil
}
// }}} m.Target = s
func (c *Context) Search(name string) []*Context { // {{{ m.Context = c
ps := make([]*Context, 0, 3)
cs := []*Context{c} return m
for i := 0; i < len(cs); i++ {
for _, v := range cs[i].Contexts {
cs = append(cs, v)
}
if strings.Contains(cs[i].Name, name) || strings.Contains(cs[i].Help, name) {
ps = append(ps, cs[i])
log.Println(c.Name, "search:", i, cs[i].Name, "[match]")
} else {
log.Println(c.Name, "search:", i, cs[i].Name)
}
}
return ps
}
// }}}
func (c *Context) Register(s *Context, self Server) bool { // {{{
if c.Contexts == nil {
c.Contexts = make(map[string]*Context)
}
if x, ok := c.Contexts[s.Name]; ok {
panic(errors.New(c.Name + " 上下文已存在" + x.Name))
}
c.Contexts[s.Name] = s
s.Context = c
s.Root = c.Root
s.Server = self
log.Println(c.Name, "register:", s.Name)
return true
}
// }}}
func (c *Context) Init(arg ...string) { // {{{
if c.Root != nil {
return
}
root := c
for root.Context != nil {
root = root.Context
}
if len(arg) > 0 {
root.Conf("log", arg[0])
} else {
root.Conf("log", root.Conf("log"))
}
if len(arg) > 1 {
root.Conf("init.sh", arg[1])
} else {
root.Conf("init.sh", root.Conf("init.sh"))
}
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)
}
}
if len(arg) > 2 {
for _, v := range arg[2:] {
cs = root.Search(v)
for _, s := range cs {
log.Println(v, "match start:", s.Name)
go s.Start()
}
}
} else {
go root.Find(strings.Split(root.Conf("default"), ".")).Start()
}
<-make(chan bool)
} }
// }}} // }}}
func (c *Context) Begin() bool { // {{{ func (c *Context) Begin() bool { // {{{
c.Root.Capi("ncontext", 1)
for k, v := range c.Configs { for k, v := range c.Configs {
c.Conf(k, v.Value) c.Conf(k, v.Value)
} }
if c.Server != nil && c.Server.Begin() { if c.Server != nil {
c.Root.Capi("ncontext", 1) return c.Server.Begin()
return true
} }
return true
return false
} }
// }}} // }}}
func (c *Context) Start() bool { // {{{ func (c *Context) Start() bool { // {{{
defer recover()
if c.Server != nil && c.Cap("status") != "start" { if c.Server != nil && c.Cap("status") != "start" {
c.Cap("status", "status", "start", "服务状态") c.Cap("status", "status", "start", "服务状态")
defer c.Cap("status", "stop") defer c.Cap("status", "stop")
@ -499,29 +486,14 @@ func (c *Context) Spawn(arg ...string) *Context { // {{{
} }
// }}} // }}}
func (c *Context) Get() *Message { // {{{
if c.Messages == nil {
c.Messages = make(chan *Message, c.Confi("MessageQueueSize"))
}
select {
case msg := <-c.Messages:
// log.Println(c.Name, "get", msg.Code, ":", msg.Meta["detail"])
return msg
}
return nil
}
// }}}
func (c *Context) Post(m *Message) bool { // {{{ func (c *Context) Post(m *Message) bool { // {{{
if c.Messages == nil { if c.Messages == nil {
c.Messages = make(chan *Message, c.Confi("MessageQueueSize")) c.Messages = make(chan *Message, c.Confi("MessageQueueSize"))
} }
m.Time = time.Now()
m.Code = c.Root.Capi("nmessage", 1) m.Code = c.Root.Capi("nmessage", 1)
// log.Println(c.Name, "post", m.Code, ":", m.Meta["detail"])
// defer log.Println(c.Name, "done", m.Code, ":", m.Meta["detail"])
c.Messages <- m c.Messages <- m
if m.Wait != nil { if m.Wait != nil {
@ -530,6 +502,15 @@ func (c *Context) Post(m *Message) bool { // {{{
return true 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 { // {{{
@ -642,13 +623,18 @@ func (c *Context) Capi(key string, value int) int { // {{{
n, e := strconv.Atoi(c.Cap(key)) n, e := strconv.Atoi(c.Cap(key))
c.Check(e) c.Check(e)
c.Cap(key, strconv.Itoa(n+value)) c.Cap(key, strconv.Itoa(n+value))
// log.Println(c.Name, "cache:", n+value) log.Println(c.Name, "cache:", key, n+value)
return n return n
} }
// }}} // }}}
// }}} // }}}
type CTX struct {
}
var Ctx = &CTX{}
var Index = &Context{Name: "ctx", Help: "根上下文", var Index = &Context{Name: "ctx", Help: "根上下文",
Caches: map[string]*Cache{ Caches: map[string]*Cache{
"status": &Cache{Name: "status", Value: "stop", Help: "服务状态"}, "status": &Cache{Name: "status", Value: "stop", Help: "服务状态"},
@ -661,22 +647,25 @@ var Index = &Context{Name: "ctx", Help: "根上下文",
"结束语": &Config{Name: "结束语", Value: "再见,上下文", Help: "结束语"}, "结束语": &Config{Name: "结束语", Value: "再见,上下文", Help: "结束语"},
"MessageQueueSize": &Config{Name: "MessageQueueSize", Value: "10", Help: "默认消息队列长度"}, "MessageQueueSize": &Config{Name: "MessageQueueSize", Value: "10", Help: "默认消息队列长度"},
"MessageListSize": &Config{Name: "MessageListSize", Value: "10", 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: "on", Help: "调试模式"},
"default": &Config{Name: "default", Value: "cli", Help: "默认启动模块"}, "default": &Config{Name: "default", Value: "cli", Help: "默认启动模块"},
"init.sh": &Config{Name: "init.sh", Value: "etc/hi.sh", Help: "默认启动脚本"}, "init.sh": &Config{Name: "init.sh", Value: "etc/init.sh", Help: "默认启动脚本"},
"log": &Config{Name: "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 {
if l, e := os.Create(arg); e == nil { // {{{ l, e := os.Create(arg) // {{{
log.SetOutput(l) c.Check(e)
} else { log.SetOutput(l)
log.Println("log", arg, "create error")
}
return arg return arg
// }}} // }}}
}}, }},
}, },
Commands: map[string]*Command{}, Commands: map[string]*Command{},
} }
func Start() {
Index.Init(os.Args[1:]...)
}

View File

@ -4,23 +4,20 @@ import (
"context" "context"
"log" "log"
"net" "net"
"time"
) )
type TCP struct { type TCP struct {
listener net.Listener listener net.Listener
conn []net.Conn
target *ctx.Context
*ctx.Context *ctx.Context
*ctx.CTX
} }
func (tcp *TCP) Begin() bool { func (tcp *TCP) Begin() bool {
tcp.conn = make([]net.Conn, 0, 3)
return true return true
} }
func (tcp *TCP) Start() bool { func (tcp *TCP) Start() bool {
log.Println(tcp.Conf("address"))
if tcp.Conf("address") == "" { if tcp.Conf("address") == "" {
return true return true
} }
@ -35,8 +32,14 @@ func (tcp *TCP) Start() bool {
c, e := l.Accept() c, e := l.Accept()
log.Println(tcp.Name, "accept:", c.LocalAddr(), "<-", c.RemoteAddr()) log.Println(tcp.Name, "accept:", c.LocalAddr(), "<-", c.RemoteAddr())
tcp.Check(e) tcp.Check(e)
tcp.conn = append(tcp.conn, c)
tcp.Capi("nclient", 1) msg := &ctx.Message{Code: tcp.Root.Capi("nmessage", 1), Time: time.Now()}
msg.Context = tcp.Resource[0].Context
msg.Index = tcp.Capi("nclient", 1)
msg.Target = tcp.Context
msg.Put("result", c)
msg.Context.Cmd(msg, "accept", c.RemoteAddr().String(), "tcp")
tcp.Resource = append(tcp.Resource, msg)
} }
return true return true
} }
@ -72,6 +75,10 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
} }
case 2: case 2:
s := c.Spawn(arg[1:]...) s := c.Spawn(arg[1:]...)
s.Resource = make([]*ctx.Message, 0, 3)
s.Resource = append(s.Resource, m)
m.Target = s
m.Index = 0
go s.Start() go s.Start()
} }
return "" return ""
@ -80,13 +87,13 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
tcp := c.Server.(*TCP) tcp := c.Server.(*TCP)
switch len(arg) { switch len(arg) {
case 1: case 1:
for i, v := range tcp.conn { for i, v := range tcp.Resource {
m.Echo(tcp.Name, "conn: %s %s -> %s\n", i, v.LocalAddr(), v.RemoteAddr()) conn := v.Data["result"].(net.Conn)
m.Echo(tcp.Name, "conn: %s %s -> %s\n", i, conn.LocalAddr(), conn.RemoteAddr())
} }
case 2: case 2:
conn, e := net.Dial("tcp", arg[1]) conn, e := net.Dial("tcp", arg[1])
c.Check(e) c.Check(e)
tcp.conn = append(tcp.conn, conn)
log.Println(tcp.Name, "dial:", conn.LocalAddr(), "->", conn.RemoteAddr()) log.Println(tcp.Name, "dial:", conn.LocalAddr(), "->", conn.RemoteAddr())
} }
return "" return ""
@ -96,6 +103,7 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
func init() { func init() {
tcp := &TCP{} tcp := &TCP{}
tcp.CTX = ctx.Ctx
tcp.Context = Index tcp.Context = Index
ctx.Index.Register(Index, tcp) ctx.Index.Register(Index, tcp)
} }

View File

@ -6,9 +6,8 @@ import (
_ "context/ssh" _ "context/ssh"
_ "context/tcp" _ "context/tcp"
_ "context/web" _ "context/web"
"os"
) )
func main() { func main() {
ctx.Index.Init(os.Args[1:]...) ctx.Start()
} }