forked from x/ContextOS
mac add message.spwan 消息添加了start, spawn, post, cmd的接口,更加完整
This commit is contained in:
parent
f67ae0b48a
commit
5a692b1aa5
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,6 @@
|
|||||||
|
bin/
|
||||||
|
var/
|
||||||
|
pkg/
|
||||||
# Binaries for programs and plugins
|
# Binaries for programs and plugins
|
||||||
*.exe
|
*.exe
|
||||||
*.dll
|
*.dll
|
||||||
|
@ -4,5 +4,3 @@ alias @ config
|
|||||||
alias $ cache
|
alias $ cache
|
||||||
alias & server
|
alias & server
|
||||||
alias * message
|
alias * message
|
||||||
|
|
||||||
remote slave listen :9393 tcp
|
|
||||||
|
@ -31,7 +31,6 @@ type CLI struct {
|
|||||||
|
|
||||||
target *ctx.Context
|
target *ctx.Context
|
||||||
*ctx.Context
|
*ctx.Context
|
||||||
*ctx.CTX
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *CLI) push(f io.ReadCloser) { // {{{
|
func (cli *CLI) push(f io.ReadCloser) { // {{{
|
||||||
@ -54,16 +53,13 @@ func (cli *CLI) parse() bool { // {{{
|
|||||||
|
|
||||||
line := ""
|
line := ""
|
||||||
if cli.next == "" {
|
if cli.next == "" {
|
||||||
l, 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 {
|
||||||
if cli.Conf("slient") != "yes" {
|
cli.echo("\n%s\n", cli.Conf("结束语"))
|
||||||
cli.echo("\n")
|
ls = "exit"
|
||||||
cli.echo(cli.Conf("结束语"))
|
e = nil
|
||||||
}
|
|
||||||
cli.echo("\n")
|
|
||||||
cli.exit <- true
|
|
||||||
} 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]
|
||||||
@ -73,7 +69,7 @@ func (cli *CLI) parse() bool { // {{{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cli.Check(e)
|
cli.Check(e)
|
||||||
line = l
|
line = ls
|
||||||
|
|
||||||
if len(cli.ins) > 1 || cli.Conf("slient") != "yes" {
|
if len(cli.ins) > 1 || cli.Conf("slient") != "yes" {
|
||||||
cli.echo(line)
|
cli.echo(line)
|
||||||
@ -129,6 +125,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"])
|
||||||
cli.Post(msg)
|
cli.Post(msg)
|
||||||
|
|
||||||
for _, v := range msg.Meta["result"] {
|
for _, v := range msg.Meta["result"] {
|
||||||
@ -143,10 +140,15 @@ 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\n", e)
|
msg.Echo("%s\n", e)
|
||||||
|
|
||||||
|
if e == io.EOF {
|
||||||
|
panic(e)
|
||||||
|
} else {
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
log.Println(e)
|
log.Println(e)
|
||||||
msg.End(false)
|
msg.End(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
detail := msg.Meta["detail"]
|
detail := msg.Meta["detail"]
|
||||||
@ -160,8 +162,8 @@ func (cli *CLI) deal(msg *ctx.Message) bool { // {{{
|
|||||||
|
|
||||||
if _, ok := cli.Commands[detail[0]]; ok {
|
if _, ok := cli.Commands[detail[0]]; ok {
|
||||||
cli.next = cli.Cmd(msg, detail...)
|
cli.next = cli.Cmd(msg, detail...)
|
||||||
} else if _, ok := cli.target.Commands[detail[0]]; ok {
|
} else if _, ok := msg.Target.Commands[detail[0]]; ok {
|
||||||
cli.next = cli.target.Cmd(msg, detail...)
|
cli.next = msg.Cmd()
|
||||||
} else {
|
} else {
|
||||||
cmd := exec.Command(detail[0], detail[1:]...)
|
cmd := exec.Command(detail[0], detail[1:]...)
|
||||||
v, e := cmd.CombinedOutput()
|
v, e := cmd.CombinedOutput()
|
||||||
@ -169,7 +171,6 @@ func (cli *CLI) deal(msg *ctx.Message) bool { // {{{
|
|||||||
msg.Echo("%s\n", e)
|
msg.Echo("%s\n", e)
|
||||||
}
|
}
|
||||||
msg.Echo(string(v))
|
msg.Echo(string(v))
|
||||||
log.Println(cli.Name, "command:", detail)
|
|
||||||
}
|
}
|
||||||
msg.End(true)
|
msg.End(true)
|
||||||
|
|
||||||
@ -190,32 +191,29 @@ func (cli *CLI) echo(str string, arg ...interface{}) { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
func (cli *CLI) Begin() bool { // {{{
|
func (cli *CLI) Begin() ctx.Server { // {{{
|
||||||
|
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 cli.Server
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
func (cli *CLI) Start(m *ctx.Message) bool { // {{{
|
||||||
|
|
||||||
|
if detail, ok := m.Data["detail"]; ok {
|
||||||
|
io := detail.(io.ReadWriteCloser)
|
||||||
|
cli.out = io
|
||||||
|
cli.push(io)
|
||||||
|
|
||||||
|
cli.echo("%s\n", cli.Conf("开场白"))
|
||||||
|
|
||||||
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" {
|
|
||||||
cli.echo("\n")
|
|
||||||
cli.echo(cli.Conf("开场白"))
|
|
||||||
cli.echo("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if cli.Conf("mode") == "local" {
|
|
||||||
go func() {
|
go func() {
|
||||||
defer recover()
|
defer recover()
|
||||||
for cli.parse() {
|
for cli.parse() {
|
||||||
@ -231,11 +229,15 @@ 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.Caches = map[string]*ctx.Cache{
|
||||||
|
"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: "监听地址"},
|
||||||
"protocol": &ctx.Config{Name: "protocol", Value: arg[1], Help: "监听协议"},
|
"protocol": &ctx.Config{Name: "protocol", Value: arg[1], Help: "监听协议"},
|
||||||
}
|
}
|
||||||
|
c.Commands = cli.Commands
|
||||||
|
c.Messages = make(chan *ctx.Message, 10)
|
||||||
|
|
||||||
s := new(CLI)
|
s := new(CLI)
|
||||||
s.Context = c
|
s.Context = c
|
||||||
@ -247,17 +249,10 @@ func (cli *CLI) Spawn(c *ctx.Context, arg ...string) ctx.Server { // {{{
|
|||||||
var Index = &ctx.Context{Name: "cli", Help: "本地控制",
|
var Index = &ctx.Context{Name: "cli", Help: "本地控制",
|
||||||
Caches: map[string]*ctx.Cache{},
|
Caches: map[string]*ctx.Cache{},
|
||||||
Configs: map[string]*ctx.Config{
|
Configs: map[string]*ctx.Config{
|
||||||
"开场白": &ctx.Config{Name: "开场白", Value: "你好,命令行", Help: "开场白"},
|
"开场白": &ctx.Config{Name: "开场白", Value: "\n~~~ Hello Context & Message World ~~~\n", Help: "开场白"},
|
||||||
"结束语": &ctx.Config{Name: "结束语", Value: "再见,命令行", Help: "结束语"},
|
"结束语": &ctx.Config{Name: "结束语", Value: "\n~~~ Byebye Context & Message World ~~~\n", Help: "结束语"},
|
||||||
"mode": &ctx.Config{Name: "mode", Value: "local", Help: "命令执行模式"},
|
"slient": &ctx.Config{Name: "slient", Value: "yes", Help: "屏蔽脚本输出"},
|
||||||
"io": &ctx.Config{Name: "io", Value: "stdout", Help: "输入输出", Hand: func(c *ctx.Context, arg string) string {
|
|
||||||
cli := c.Server.(*CLI) // {{{
|
|
||||||
cli.out = os.Stdout
|
|
||||||
cli.push(os.Stdin)
|
|
||||||
return arg
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"slient": &ctx.Config{Name: "slient", Value: "yes", 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 {
|
||||||
@ -356,29 +351,13 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
|
|||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"message": &ctx.Command{"message detail...", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
|
"message": &ctx.Command{"message detail...", "查看上下文", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
|
||||||
m := ctx.Pulse
|
// {{{
|
||||||
switch len(arg) {
|
ms := []*ctx.Message{ctx.Pulse}
|
||||||
case 1:
|
for i := 0; i < len(ms); i++ {
|
||||||
fmt.Println(msg.Code, msg.Time.Format("2006/01/02 15:04:05"))
|
m.Echo("%d %s.%s -> %s.%d\n", ms[i].Code, ms[i].Context.Name, ms[i].Name, ms[i].Target.Name, ms[i].Index)
|
||||||
case 2:
|
// m.Echo("%d %s %s.%s -> %s.%d\n", ms[i].Code, ms[i].Time.Format("2006/01/02 15:03:04"), ms[i].Context.Name, ms[i].Name, ms[i].Target.Name, ms[i].Index)
|
||||||
switch arg[1] {
|
ms = append(ms, ms[i].Messages...)
|
||||||
case "home":
|
|
||||||
m = msg.Message
|
|
||||||
case "root":
|
|
||||||
}
|
|
||||||
fmt.Println(m.Code, m.Time.Format("2006/01/02 15:04:05"))
|
|
||||||
for i, v := range m.Messages {
|
|
||||||
fmt.Println(i, v.Code, v.Time.Format("2006/01/02 15:04:05"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
msg.Meta["detail"] = arg[1:] // {{{
|
|
||||||
if c == msg.Target {
|
|
||||||
go msg.Target.Post(msg)
|
|
||||||
} else {
|
|
||||||
msg.Target.Post(msg)
|
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
@ -392,7 +371,7 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
|
|||||||
switch arg[1] {
|
switch arg[1] {
|
||||||
case "start":
|
case "start":
|
||||||
if s != nil {
|
if s != nil {
|
||||||
go s.Start()
|
go s.Start(msg)
|
||||||
}
|
}
|
||||||
case "stop":
|
case "stop":
|
||||||
case "switch":
|
case "switch":
|
||||||
@ -525,8 +504,11 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
|
|||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
|
"exit": &ctx.Command{"exit", "退出", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
|
||||||
|
panic(io.EOF)
|
||||||
|
}},
|
||||||
"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) { // {{{
|
||||||
case 1:
|
case 1:
|
||||||
case 5:
|
case 5:
|
||||||
if arg[1] == "master" {
|
if arg[1] == "master" {
|
||||||
@ -535,23 +517,19 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if arg[2] == "listen" {
|
if arg[2] == "listen" {
|
||||||
msg := &ctx.Message{Code: c.Root.Capi("nmessage", 1), Time: time.Now()}
|
s := c.Root.Find(strings.Split(arg[4], "."))
|
||||||
msg.Add("mode", "local")
|
m.Message.Spawn(s, arg[3], 0).Add("detail", "listen", arg[3]).Post(c)
|
||||||
msg.Target = c.Root.Find(strings.Split(arg[4], "."))
|
|
||||||
msg.Context = m.Context
|
|
||||||
msg.Target.Cmd(msg, "listen", arg[3])
|
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
// }}}
|
||||||
}},
|
}},
|
||||||
"accept": &ctx.Command{"accept address protocl", "建立远程连接", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
|
"accept": &ctx.Command{"accept address protocl", "建立远程连接", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
|
||||||
s := msg.Context.Spawn(arg[1], arg[2])
|
m.Start(arg[1:]...) // {{{
|
||||||
s.Session = make(map[string]*ctx.Message)
|
|
||||||
s.Session["remote"] = msg
|
|
||||||
s.Start()
|
|
||||||
return ""
|
return ""
|
||||||
|
// }}}
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
Messages: make(chan *ctx.Message, 10),
|
Messages: make(chan *ctx.Message, 10),
|
||||||
@ -559,7 +537,6 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cli := &CLI{}
|
cli := &CLI{}
|
||||||
cli.CTX = ctx.Ctx
|
|
||||||
cli.Context = Index
|
cli.Context = Index
|
||||||
ctx.Index.Register(Index, cli)
|
ctx.Index.Register(Index, cli)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import ( // {{{
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"regexp"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -38,43 +39,50 @@ type Command struct { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
type Message struct { // {{{
|
type Message struct { // {{{
|
||||||
Time time.Time
|
|
||||||
Code int
|
Code int
|
||||||
User string
|
Time time.Time
|
||||||
|
|
||||||
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
|
|
||||||
*Context
|
*Context
|
||||||
|
Name string
|
||||||
|
Target *Context
|
||||||
|
Index int
|
||||||
|
|
||||||
Messages []*Message
|
Messages []*Message
|
||||||
Message *Message
|
Message *Message
|
||||||
Root *Message
|
Root *Message
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) Spawn(c *Context, key string) *Message { // {{{
|
func (m *Message) Spawn(c *Context, key string, index int) *Message { // {{{
|
||||||
msg := &Message{Time: time.Now(), Code: m.Capi("nmessage", 1)}
|
msg := &Message{
|
||||||
|
Code: m.Capi("nmessage", 1),
|
||||||
|
Time: time.Now(),
|
||||||
|
Target: c,
|
||||||
|
Name: key,
|
||||||
|
Message: m,
|
||||||
|
Root: m.Root,
|
||||||
|
}
|
||||||
|
|
||||||
msg.Context = m.Target
|
msg.Context = m.Target
|
||||||
msg.Target = c
|
if msg.Session == nil {
|
||||||
|
msg.Session = make(map[string]*Message)
|
||||||
|
}
|
||||||
|
msg.Session[key] = msg
|
||||||
|
|
||||||
if m.Messages == nil {
|
if m.Messages == nil {
|
||||||
m.Messages = make([]*Message, 0, 10)
|
m.Messages = make([]*Message, 0, 10)
|
||||||
}
|
}
|
||||||
m.Messages = append(m.Messages, msg)
|
m.Messages = append(m.Messages, msg)
|
||||||
msg.Message = m
|
log.Printf("%d spawn %d: %s.%s->%s.%d", m.Code, msg.Code, msg.Context.Name, msg.Name, msg.Target.Name, msg.Index)
|
||||||
msg.Root = m.Root
|
return msg
|
||||||
return m
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (m *Message) Add(key string, value ...string) string { // {{{
|
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)
|
||||||
}
|
}
|
||||||
@ -83,17 +91,17 @@ func (m *Message) Add(key string, value ...string) string { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.Meta[key] = append(m.Meta[key], value...)
|
m.Meta[key] = append(m.Meta[key], value...)
|
||||||
return value[0]
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (m *Message) Put(key string, value interface{}) interface{} { // {{{
|
func (m *Message) Put(key string, value interface{}) *Message { // {{{
|
||||||
if m.Data == nil {
|
if m.Data == nil {
|
||||||
m.Data = make(map[string]interface{})
|
m.Data = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Data[key] = value
|
m.Data[key] = value
|
||||||
return value
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
@ -116,7 +124,7 @@ func (m *Message) Get(key string) string { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (m *Message) Echo(str string, arg ...interface{}) string { // {{{
|
func (m *Message) Echo(str string, arg ...interface{}) *Message { // {{{
|
||||||
if m.Meta == nil {
|
if m.Meta == nil {
|
||||||
m.Meta = make(map[string][]string)
|
m.Meta = make(map[string][]string)
|
||||||
}
|
}
|
||||||
@ -126,7 +134,7 @@ func (m *Message) Echo(str string, arg ...interface{}) string { // {{{
|
|||||||
|
|
||||||
s := fmt.Sprintf(str, arg...)
|
s := fmt.Sprintf(str, arg...)
|
||||||
m.Meta["result"] = append(m.Meta["result"], s)
|
m.Meta["result"] = append(m.Meta["result"], s)
|
||||||
return s
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
@ -137,11 +145,38 @@ func (m *Message) End(s bool) { // {{{
|
|||||||
m.Wait = nil
|
m.Wait = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
func (m *Message) Cmd() string { // {{{
|
||||||
|
return m.Target.Cmd(m, m.Meta["detail"]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
func (m *Message) Post(c *Context) 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 (m *Message) Start(arg ...string) bool { // {{{
|
||||||
|
s := m.Target.Spawn(arg...).Begin()
|
||||||
|
m.Target = s
|
||||||
|
go s.Start(m)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
// }}}
|
// }}}
|
||||||
type Server interface { // {{{
|
type Server interface { // {{{
|
||||||
Begin() bool
|
Begin() Server
|
||||||
Start() bool
|
Start(m *Message) bool
|
||||||
Spawn(c *Context, arg ...string) Server
|
Spawn(c *Context, arg ...string) Server
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,18 +245,6 @@ func (c *Context) Init(arg ...string) { // {{{
|
|||||||
root = root.Context
|
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}
|
cs := []*Context{root}
|
||||||
|
|
||||||
for i := 0; i < len(cs); i++ {
|
for i := 0; i < len(cs); i++ {
|
||||||
@ -233,38 +256,39 @@ func (c *Context) Init(arg ...string) { // {{{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pulse.Context = Index
|
|
||||||
Pulse.Root = Pulse
|
Pulse.Root = Pulse
|
||||||
|
Pulse.Target = Index
|
||||||
|
Pulse.Context = Index
|
||||||
|
|
||||||
if len(arg) > 2 {
|
for _, s := range root.Contexts {
|
||||||
for _, v := range arg[2:] {
|
if ok, _ := regexp.MatchString(root.Conf("start"), s.Name); ok {
|
||||||
cs = root.Search(v)
|
go s.Start(Pulse.Spawn(s, s.Name, 0).Put("detail", os.Stdout))
|
||||||
for _, s := range cs {
|
|
||||||
go s.Start()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
s := root.Find(strings.Split(root.Conf("default"), "."))
|
|
||||||
go s.Start()
|
|
||||||
Pulse.Target = s
|
|
||||||
s.Post(Pulse)
|
|
||||||
}
|
|
||||||
|
|
||||||
<-make(chan bool)
|
Pulse.Wait = make(chan bool)
|
||||||
|
for {
|
||||||
|
<-Pulse.Wait
|
||||||
|
if Index.Capi("nserver", 0) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (c *Context) Find(name []string) *Context { // {{{
|
func (c *Context) Find(name []string) (s *Context) { // {{{
|
||||||
if x, ok := c.Contexts[name[0]]; ok {
|
log.Println(c.Name, "find:", name)
|
||||||
log.Println(c.Name, "find:", x.Name)
|
|
||||||
if len(name) == 1 {
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
return x.Find(name[1:])
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println(c.Name, "not find:", name[0])
|
cs := c.Contexts
|
||||||
return nil
|
for _, v := range name {
|
||||||
|
if x, ok := cs[v]; ok {
|
||||||
|
s = x
|
||||||
|
cs = x.Contexts
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
panic(errors.New("not find: " + v))
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
@ -454,32 +478,41 @@ func (c *Context) Del(arg ...string) { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
func (c *Context) Begin() bool { // {{{
|
func (c *Context) Begin() *Context { // {{{
|
||||||
c.Root.Capi("ncontext", 1)
|
c.Root.Capi("ncontext", 1)
|
||||||
for k, v := range c.Configs {
|
for _, v := range c.Configs {
|
||||||
c.Conf(k, v.Value)
|
if v.Hand != nil {
|
||||||
|
v.Hand(c, v.Value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Server != nil {
|
if c.Server != nil {
|
||||||
return c.Server.Begin()
|
c.Server.Begin()
|
||||||
}
|
}
|
||||||
return true
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (c *Context) Start() bool { // {{{
|
func (c *Context) Start(m *Message) bool { // {{{
|
||||||
defer recover()
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
log.Println(e)
|
||||||
|
}
|
||||||
|
Pulse.Wait <- true
|
||||||
|
}()
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
c.Root.Capi("nserver", 1)
|
c.Root.Capi("nserver", 1)
|
||||||
defer c.Root.Capi("nserver", -1)
|
defer c.Root.Capi("nserver", -1)
|
||||||
|
|
||||||
log.Println(c.Name, "start:")
|
c.Resource = []*Message{m}
|
||||||
c.Server.Start()
|
log.Println(m.Code, "start:", c.Name)
|
||||||
log.Println(c.Name, "stop:")
|
c.Server.Start(m)
|
||||||
|
log.Println(m.Code, "stop:", c.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -490,8 +523,6 @@ func (c *Context) Spawn(arg ...string) *Context { // {{{
|
|||||||
s := &Context{Name: arg[0], Help: c.Help}
|
s := &Context{Name: arg[0], Help: c.Help}
|
||||||
c.Register(s, c.Server.Spawn(s, arg...))
|
c.Register(s, c.Server.Spawn(s, arg...))
|
||||||
s.Begin()
|
s.Begin()
|
||||||
|
|
||||||
log.Println(c.Name, "spawn:", s.Name)
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,10 +532,6 @@ 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"))
|
||||||
}
|
}
|
||||||
if c.Resource == nil {
|
|
||||||
c.Resource = make([]*Message, 0, c.Confi("MessageQueueSize"))
|
|
||||||
}
|
|
||||||
c.Resource = append(c.Resource, m)
|
|
||||||
|
|
||||||
c.Messages <- m
|
c.Messages <- m
|
||||||
if m.Wait != nil {
|
if m.Wait != nil {
|
||||||
@ -526,7 +553,6 @@ func (c *Context) Get() *Message { // {{{
|
|||||||
|
|
||||||
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 {
|
||||||
log.Println(c.Name, "command:", arg)
|
|
||||||
return x.Hand(c, m, arg...)
|
return x.Hand(c, m, arg...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,12 +641,12 @@ func (c *Context) Cap(arg ...string) string { // {{{
|
|||||||
return c.Context.Cap(arg...)
|
return c.Context.Cap(arg...)
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
if v, ok := c.Caches[arg[0]]; ok {
|
// if v, ok := c.Caches[arg[0]]; ok {
|
||||||
panic(errors.New(v.Name + "缓存项已存在"))
|
// panic(errors.New(v.Name + "缓存项已存在"))
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
c.Caches[arg[0]] = &Cache{arg[1], arg[2], arg[3], nil}
|
c.Caches[arg[0]] = &Cache{arg[1], arg[2], arg[3], nil}
|
||||||
log.Println(c.Name, "cache:", arg)
|
// log.Println(c.Name, "cache:", arg)
|
||||||
return arg[2]
|
return arg[2]
|
||||||
default:
|
default:
|
||||||
panic(errors.New(arg[0] + "缓存项参数错误"))
|
panic(errors.New(arg[0] + "缓存项参数错误"))
|
||||||
@ -634,17 +660,12 @@ 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:", key, n+value)
|
return n + value
|
||||||
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: "服务状态"},
|
||||||
@ -663,7 +684,7 @@ var Index = &Context{Name: "ctx", 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: "默认启动模块"},
|
"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 {
|
||||||
l, e := os.Create(arg) // {{{
|
l, e := os.Create(arg) // {{{
|
||||||
@ -675,10 +696,27 @@ var Index = &Context{Name: "ctx", Help: "根上下文",
|
|||||||
},
|
},
|
||||||
Commands: map[string]*Command{},
|
Commands: map[string]*Command{},
|
||||||
Session: map[string]*Message{"root": Pulse},
|
Session: map[string]*Message{"root": Pulse},
|
||||||
|
Resource: []*Message{Pulse},
|
||||||
}
|
}
|
||||||
|
|
||||||
var Pulse = &Message{Time: time.Now(), Code: 0}
|
var Pulse = &Message{Code: 0, Time: time.Now(), Index: 0, Name: "root"}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
Index.Conf("bench.log", os.Args[1])
|
||||||
|
} else {
|
||||||
|
Index.Conf("bench.log", Index.Conf("bench.log"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(os.Args) > 2 {
|
||||||
|
Index.Conf("init.sh", os.Args[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(os.Args) > 3 {
|
||||||
|
Index.Conf("start", os.Args[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Start() {
|
func Start() {
|
||||||
Index.Init(os.Args[1:]...)
|
Index.Init()
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
package tcp
|
package tcp // {{{
|
||||||
|
// }}}
|
||||||
import (
|
import ( // {{{
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
type TCP struct {
|
type TCP struct {
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
*ctx.Context
|
*ctx.Context
|
||||||
*ctx.CTX
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tcp *TCP) Begin() bool {
|
func (tcp *TCP) Begin() ctx.Server { // {{{
|
||||||
return true
|
return tcp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tcp *TCP) Start() bool {
|
// }}}
|
||||||
|
func (tcp *TCP) Start(m *ctx.Message) bool { // {{{
|
||||||
if tcp.Conf("address") == "" {
|
if tcp.Conf("address") == "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -33,18 +34,15 @@ func (tcp *TCP) Start() bool {
|
|||||||
log.Println(tcp.Name, "accept:", c.LocalAddr(), "<-", c.RemoteAddr())
|
log.Println(tcp.Name, "accept:", c.LocalAddr(), "<-", c.RemoteAddr())
|
||||||
tcp.Check(e)
|
tcp.Check(e)
|
||||||
|
|
||||||
msg := &ctx.Message{Code: tcp.Root.Capi("nmessage", 1), Time: time.Now()}
|
m := m.Spawn(m.Context, c.RemoteAddr().String(), 0)
|
||||||
msg.Context = tcp.Resource[0].Context
|
m.Add("detail", "accept", c.RemoteAddr().String(), "tcp").Put("detail", c).Cmd()
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tcp *TCP) Spawn(c *ctx.Context, arg ...string) ctx.Server {
|
// }}}
|
||||||
|
func (tcp *TCP) Spawn(c *ctx.Context, 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: "连接数量"},
|
||||||
}
|
}
|
||||||
@ -55,8 +53,11 @@ func (tcp *TCP) Spawn(c *ctx.Context, arg ...string) ctx.Server {
|
|||||||
s := new(TCP)
|
s := new(TCP)
|
||||||
s.Context = c
|
s.Context = c
|
||||||
return s
|
return s
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
|
var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
|
||||||
Caches: map[string]*ctx.Cache{
|
Caches: map[string]*ctx.Cache{
|
||||||
"nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"},
|
"nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"},
|
||||||
@ -66,25 +67,20 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
|
|||||||
"address": &ctx.Config{Name: "address", Value: "", Help: "监听地址"},
|
"address": &ctx.Config{Name: "address", Value: "", Help: "监听地址"},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
"listen": &ctx.Command{"listen", "监听端口", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
|
"listen": &ctx.Command{"listen address", "监听端口", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
|
||||||
switch len(arg) {
|
switch len(arg) { // {{{
|
||||||
case 1:
|
case 1:
|
||||||
for k, s := range c.Contexts {
|
for k, s := range m.Target.Contexts {
|
||||||
x := s.Server.(*TCP)
|
m.Echo("%s %s\n", k, s.Server.(*TCP).listener.Addr().String())
|
||||||
m.Echo("%s %s\n", k, x.listener.Addr().String())
|
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
s := c.Spawn(arg[1:]...)
|
m.Start(arg[1:]...)
|
||||||
s.Resource = make([]*ctx.Message, 0, 3)
|
|
||||||
s.Resource = append(s.Resource, m)
|
|
||||||
m.Target = s
|
|
||||||
m.Index = 0
|
|
||||||
go s.Start()
|
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
// }}}
|
||||||
}},
|
}},
|
||||||
"dial": &ctx.Command{"dial", "建立连接", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
|
"dial": &ctx.Command{"dial", "建立连接", func(c *ctx.Context, m *ctx.Message, arg ...string) string {
|
||||||
tcp := c.Server.(*TCP)
|
tcp := c.Server.(*TCP) // {{{
|
||||||
switch len(arg) {
|
switch len(arg) {
|
||||||
case 1:
|
case 1:
|
||||||
for i, v := range tcp.Resource {
|
for i, v := range tcp.Resource {
|
||||||
@ -97,13 +93,13 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
|
|||||||
log.Println(tcp.Name, "dial:", conn.LocalAddr(), "->", conn.RemoteAddr())
|
log.Println(tcp.Name, "dial:", conn.LocalAddr(), "->", conn.RemoteAddr())
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
// }}}
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
_ "context/cli"
|
_ "context/cli"
|
||||||
_ "context/ssh"
|
|
||||||
_ "context/tcp"
|
_ "context/tcp"
|
||||||
_ "context/web"
|
// _ "context/ssh"
|
||||||
|
// _ "context/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user