From 755c29eea3dd96a6fd7e38e33a5392bd95fd5379 Mon Sep 17 00:00:00 2001 From: shy Date: Tue, 5 Apr 2022 00:46:50 +0800 Subject: [PATCH] add udp --- base/web/broad.go | 81 +++++++++++++++++++++++++++++++++++++++++++++++ base/web/dream.go | 4 ++- base/web/serve.go | 4 +++ base/web/web.go | 1 + go.sum | 2 ++ type.go | 8 +++++ 6 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 base/web/broad.go diff --git a/base/web/broad.go b/base/web/broad.go new file mode 100644 index 00000000..48fccb94 --- /dev/null +++ b/base/web/broad.go @@ -0,0 +1,81 @@ +package web + +import ( + "net" + + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/tcp" + kit "shylinux.com/x/toolkits" +) + +func _udp_addr(m *ice.Message, host, port string) *net.UDPAddr { + addr, err := net.ResolveUDPAddr("udp4", kit.Format("%s:%s", host, port)) + m.Assert(err) + return addr +} +func _udp_broad(m *ice.Message, host, port string, remote_host, remote_port string) { + if s, e := net.DialUDP("udp", nil, _udp_addr(m, remote_host, remote_port)); m.Assert(e) { + defer s.Close() + msg := m.Spawn(kit.Dict(tcp.HOST, host, tcp.PORT, port)) + m.Debug("broad %v to %v:%v", msg.FormatMeta(), remote_host, remote_port) + s.Write([]byte(msg.FormatMeta())) + } +} +func _serve_udp(m *ice.Message, host, port string) { + m.Cmd(BROAD, mdb.CREATE, tcp.HOST, host, tcp.PORT, port) + _udp_broad(m, host, port, "255.255.255.255", "9020") + + if s, e := net.ListenUDP("udp", _udp_addr(m, "0.0.0.0", port)); m.Assert(e) { + defer s.Close() + m.Debug("listen %v %v", host, port) + + buf := make([]byte, 1024) + for { + n, addr, err := s.ReadFromUDP(buf[:]) + if err != nil { + m.Debug("what %v", err) + continue + } + m.Debug("recv %v %v", string(buf[:n]), addr) + + msg := m.Spawn(buf[:n]) + if m.Cmd(BROAD, kit.Format("%s,%s", msg.Option(tcp.HOST), msg.Option(tcp.PORT))).Length() > 0 { + continue + } + + if remote, err := net.ResolveUDPAddr("udp4", kit.Format("%s:%s", msg.Option(tcp.HOST), msg.Option(tcp.PORT))); err == nil { + m.Cmd(BROAD).Table(func(index int, value map[string]string, head []string) { + m.Debug("broad %v to %v", kit.Format(value), kit.Format(remote)) + s.WriteToUDP([]byte(m.Spawn(value).FormatMeta()), remote) + }) + m.Cmd(BROAD, mdb.CREATE, msg.OptionSimple(tcp.HOST, tcp.PORT)) + } else { + m.Debug("what %v", err) + } + } + } +} + +const BROAD = "broad" + +func init() { + Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ + BROAD: {Name: "broad hash auto", Help: "广播", Action: ice.MergeAction(map[string]*ice.Action{ + SERVE: {Name: "broad port=9020", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { + _serve_udp(m, m.Cmd(tcp.HOST).Append("ip"), m.Option(tcp.PORT)) + }}, + SPACE: {Name: "space dev", Help: "连接", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(SPIDE, mdb.CREATE, mdb.NAME, m.Option(ice.DEV), ADDRESS, + kit.Format("http://%s:%s", m.Option(tcp.HOST), m.Option(tcp.PORT))) + m.Cmd(SPACE, tcp.DIAL, m.OptionSimple(ice.DEV)) + }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { m.Conf(BROAD, "", "") }}, + }, mdb.HashAction( + mdb.SHORT, "host,port", mdb.FIELD, "time,hash,host,port", + )), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + mdb.HashSelect(m, arg...) + m.PushAction(SPACE, mdb.REMOVE) + }}, + }}) +} diff --git a/base/web/dream.go b/base/web/dream.go index 0056a6eb..2dcdaf30 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -156,7 +156,9 @@ func init() { } }) m.Sort("status,type,name") - m.Display("/plugin/table.js", "style", "card") + if !strings.Contains(m.Option(ice.MSG_USERUA), "Mobile") { + m.Display("/plugin/table.js", "style", "card") + } return } diff --git a/base/web/serve.go b/base/web/serve.go index 2ba2a04f..6afd0171 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -308,6 +308,9 @@ func init() { DOMAIN: {Name: "domain", Help: "域名", Hand: func(m *ice.Message, arg ...string) { ice.Info.Domain = m.Conf(SHARE, kit.Keym(DOMAIN, m.Config(DOMAIN, arg[0]))) }}, + "list_broad": {Name: "list_broad", Help: "服务发现", Hand: func(m *ice.Message, arg ...string) { + m.Go(func() { _serve_udp(m, m.Cmd(tcp.HOST).Append("ip"), m.Option(tcp.PORT)) }) + }}, aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) { for _, k := range arg { m.Log_CREATE(aaa.BLACK, k) @@ -330,6 +333,7 @@ func init() { m.Config("staffname", m.Option("staffname")) } aaa.UserRoot(m, m.Option(aaa.PASSWORD), m.Option(aaa.USERNAME), m.Option(aaa.USERROLE)) + m.Go(func() { m.Cmd(BROAD, SERVE) }) m.Target().Start(m, m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT)...) m.Sleep300ms() diff --git a/base/web/web.go b/base/web/web.go index 86f9fa06..dd71edf3 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -106,5 +106,6 @@ func init() { ice.Index.Register(Index, &Frame{}, SERVE, SPACE, DREAM, ROUTE, SHARE, SPIDE, CACHE, STORY, + BROAD, ) } diff --git a/go.sum b/go.sum index 4d0d1da8..c40c252a 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ +shylinux.com/x/go-qrcode v0.0.1 h1:/eOGqMj1qtgs9Ymd12zTUa1gcJZs9S92kj2lb0QzKsE= shylinux.com/x/go-qrcode v0.0.1/go.mod h1:KAbtU+KwiiABMZ/CJ0zh9PI2AX82Uf9rRYcQ4ODm4po= shylinux.com/x/toolkits v0.5.6 h1:iSwkPBbRaqfPfeNePpVafjbQdVkdR2nY9FXMCxrwwfw= shylinux.com/x/toolkits v0.5.6/go.mod h1:8LbYHe7oxBIqb6s4MSOD+4d28QvPdvkyCVtwB/JW7AA= +shylinux.com/x/websocket v0.0.1 h1:OBc21DxqsGlQ2+Pz76xqLyDNo1LV+PUUqfWi+1PZPDE= shylinux.com/x/websocket v0.0.1/go.mod h1:AaSpMToOxbMULKQytzczeHPuqb708vK1vrAzCxLo/XE= diff --git a/type.go b/type.go index f7fa7090..a3ead4f2 100644 --- a/type.go +++ b/type.go @@ -315,6 +315,14 @@ func (m *Message) Spawn(arg ...interface{}) *Message { msg.target = val case string: msg._key = val + case map[string]string: + for k, v := range val { + msg.Option(k, v) + } + case map[string]interface{}: + for k, v := range val { + msg.Option(k, v) + } } } return msg