forked from x/ContextOS
add web.wss
This commit is contained in:
parent
16f7cde6bb
commit
78be157b5d
@ -4,5 +4,5 @@ var version = struct {
|
|||||||
host string
|
host string
|
||||||
self int
|
self int
|
||||||
}{
|
}{
|
||||||
"2019-09-22 09:30:17", "mac", 632,
|
"2019-09-22 15:44:02", "mac", 660,
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package ctx
|
package ctx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"runtime"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"toolkit"
|
"toolkit"
|
||||||
@ -382,7 +382,10 @@ func (m *Message) Call(cb func(msg *Message) (sub *Message), arg ...interface{})
|
|||||||
if m == nil {
|
if m == nil {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
if m.callback = cb; len(arg) > 0 || len(m.Meta["detail"]) > 0 {
|
if m.callback = cb; len(arg) > 0 && kit.Format(arg[0]) == "skip" {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
if len(arg) > 0 || len(m.Meta["detail"]) > 0 {
|
||||||
m.Log("call", m.Format("detail", "option"))
|
m.Log("call", m.Format("detail", "option"))
|
||||||
m.Cmd(arg...)
|
m.Cmd(arg...)
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,7 @@ type Message struct {
|
|||||||
Hand bool
|
Hand bool
|
||||||
Meta map[string][]string
|
Meta map[string][]string
|
||||||
Data map[string]interface{}
|
Data map[string]interface{}
|
||||||
|
Sync chan bool
|
||||||
|
|
||||||
callback func(msg *Message) (sub *Message)
|
callback func(msg *Message) (sub *Message)
|
||||||
freeback []func(msg *Message) (done bool)
|
freeback []func(msg *Message) (done bool)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
"github.com/skip2/go-qrcode"
|
"github.com/skip2/go-qrcode"
|
||||||
|
|
||||||
"contexts/ctx"
|
"contexts/ctx"
|
||||||
@ -119,7 +120,8 @@ func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request)
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if relay.Appends("username") {
|
if relay.Appends("username") {
|
||||||
msg.Log("info", "login: %s", msg.Option("username", relay.Append("username")))
|
name := msg.Cmdx("ssh._route", msg.Conf("runtime", "work.route"), "_check", "work", "create", relay.Append("username"), msg.Conf("runtime", "node.route"))
|
||||||
|
msg.Log("info", "login: %s", msg.Option("username", name))
|
||||||
http.SetCookie(w, &http.Cookie{Name: "sessid", Value: msg.Option("sessid", msg.Cmdx("aaa.user", "session", "select")), Path: "/"})
|
http.SetCookie(w, &http.Cookie{Name: "sessid", Value: msg.Option("sessid", msg.Cmdx("aaa.user", "session", "select")), Path: "/"})
|
||||||
}
|
}
|
||||||
if role := relay.Append("userrole"); role != "" {
|
if role := relay.Append("userrole"); role != "" {
|
||||||
@ -425,6 +427,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
|||||||
"toolkit": &ctx.Config{Name: "toolkit", Value: map[string]interface{}{
|
"toolkit": &ctx.Config{Name: "toolkit", Value: map[string]interface{}{
|
||||||
"time": map[string]interface{}{"cmd": "time"},
|
"time": map[string]interface{}{"cmd": "time"},
|
||||||
}, Help: "工具列表"},
|
}, Help: "工具列表"},
|
||||||
|
"wss": &ctx.Config{Name: "wss", Value: map[string]interface{}{}, Help: ""},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
"_init": &ctx.Command{Name: "_init", Help: "post请求", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
"_init": &ctx.Command{Name: "_init", Help: "post请求", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||||
@ -1081,6 +1084,122 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}},
|
}},
|
||||||
|
|
||||||
|
"/wss": &ctx.Command{Name: "/wss", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||||
|
r := m.Optionv("request").(*http.Request)
|
||||||
|
w := m.Optionv("response").(http.ResponseWriter)
|
||||||
|
|
||||||
|
if s, e := websocket.Upgrade(w, r, nil, 4096, 4096); m.Assert(e) {
|
||||||
|
h := kit.Hashs("uniq")
|
||||||
|
p := make(chan *ctx.Message, 10)
|
||||||
|
meta := map[string]interface{}{
|
||||||
|
"create_time": m.Time(),
|
||||||
|
"create_user": m.Option("username"),
|
||||||
|
"agent": r.Header.Get("User-Agent"),
|
||||||
|
"sessid": m.Option("sessid"),
|
||||||
|
"socket": s,
|
||||||
|
"channel": p,
|
||||||
|
}
|
||||||
|
m.Conf("wss", []string{m.Option("username"), h}, meta)
|
||||||
|
m.Conf("wss", h, meta)
|
||||||
|
|
||||||
|
what := m
|
||||||
|
m.Log("info", "wss conn %v", h)
|
||||||
|
m.Gos(m.Spawn(), func(msg *ctx.Message) {
|
||||||
|
for {
|
||||||
|
if t, b, e := s.ReadMessage(); e == nil {
|
||||||
|
var data interface{}
|
||||||
|
if e := json.Unmarshal(b, &data); e == nil {
|
||||||
|
m.Log("info", "wss recv %s %d msg %v", h, t, data)
|
||||||
|
} else {
|
||||||
|
m.Log("warn", "wss recv %s %d msg %v", h, t, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
what.Optionv("data", data)
|
||||||
|
what.Back(what)
|
||||||
|
} else {
|
||||||
|
m.Log("warn", "wss recv %s %d msg %v", h, t, e)
|
||||||
|
close(p)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
for what = range p {
|
||||||
|
s.WriteJSON(what.Meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Close()
|
||||||
|
m.Conf("wss", h, "")
|
||||||
|
m.Conf("wss", []string{m.Option("username"), h}, "")
|
||||||
|
m.Log("warn", "wss close %s", h)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}},
|
||||||
|
"wss": &ctx.Command{Name: "wss", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||||
|
if len(arg) == 0 {
|
||||||
|
m.Confm("wss", func(key string, value map[string]interface{}) {
|
||||||
|
if value["agent"] == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m.Push("key", m.Cmdx("aaa.short", key))
|
||||||
|
m.Push("create_time", value["create_time"])
|
||||||
|
m.Push("create_user", value["create_user"])
|
||||||
|
m.Push("sessid", kit.Format(value["sessid"])[:6])
|
||||||
|
m.Push("agent", value["agent"])
|
||||||
|
})
|
||||||
|
m.Table()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
list := []string{}
|
||||||
|
if strings.Contains(arg[0], ".") {
|
||||||
|
vs := strings.SplitN(arg[0], ".", 2)
|
||||||
|
m.Confm("wss", vs[0], func(key string, value map[string]interface{}) {
|
||||||
|
if vs[1] == "*" || strings.Contains(kit.Format(value["agent"]), vs[1]) {
|
||||||
|
list = append(list, key)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if len(arg[0]) != 32 {
|
||||||
|
arg[0] = m.Cmdx("aaa.short", arg[0])
|
||||||
|
}
|
||||||
|
list = append(list, arg[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(arg) == 1 {
|
||||||
|
m.Cmdy(".config", "wss", arg[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range list {
|
||||||
|
if p, ok := m.Confv("wss", []string{v, "channel"}).(chan *ctx.Message); ok {
|
||||||
|
if arg[1] == "sync" {
|
||||||
|
m.Meta["detail"] = arg[2:]
|
||||||
|
p <- m
|
||||||
|
m.CallBack(true, func(msg *ctx.Message) *ctx.Message {
|
||||||
|
if data, ok := m.Optionv("data").(map[string]interface{}); ok {
|
||||||
|
res := kit.Trans(data["result"])
|
||||||
|
m.Log("info", "result: %v", res)
|
||||||
|
if len(res) > 0 {
|
||||||
|
m.Result(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Push("time", m.Time())
|
||||||
|
m.Push("key", m.Cmdx("aaa.short", v))
|
||||||
|
m.Push("action", kit.Format(arg[2:]))
|
||||||
|
m.Push("result", kit.Format(m.Meta["result"]))
|
||||||
|
return nil
|
||||||
|
}, "skip")
|
||||||
|
} else {
|
||||||
|
m.Meta["detail"] = arg[1:]
|
||||||
|
p <- m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +195,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
|||||||
if !m.Options("sessid") || !m.Options("username") {
|
if !m.Options("sessid") || !m.Options("username") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
m.Short("river")
|
||||||
|
|
||||||
// 自动入群
|
// 自动入群
|
||||||
if m.Options("river") {
|
if m.Options("river") {
|
||||||
|
@ -48,3 +48,10 @@ fun media "娱乐" private \
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
kit wss "推送" private "web.wss" \
|
||||||
|
text "" name wss imports plugin_wss \
|
||||||
|
text "" name cmd \
|
||||||
|
button "推送" \
|
||||||
|
button "返回" click Last \
|
||||||
|
exports wss key
|
||||||
|
|
||||||
|
@ -317,6 +317,12 @@ func Map(v interface{}, random string, args ...interface{}) map[string]interface
|
|||||||
fun(i, val)
|
fun(i, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case func(string, []interface{}):
|
||||||
|
for k, v := range value {
|
||||||
|
if val, ok := v.([]interface{}); ok {
|
||||||
|
fun(k, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
case func(string, map[string]interface{}):
|
case func(string, map[string]interface{}):
|
||||||
switch random {
|
switch random {
|
||||||
case "%":
|
case "%":
|
||||||
|
@ -280,7 +280,7 @@ var page = Page({check: true,
|
|||||||
], 0)
|
], 0)
|
||||||
},
|
},
|
||||||
Core: function(event, line, args, cbs) {
|
Core: function(event, line, args, cbs) {
|
||||||
var plugin = event.Plugin || {}, engine = {
|
var plugin = event.Plugin || page.plugin && page.plugin.Plugin || {}, engine = {
|
||||||
share: function(args) {
|
share: function(args) {
|
||||||
typeof cbs == "function" && cbs(ctx.Share({"group": option.dataset.group, "name": option.dataset.name, "cmds": [
|
typeof cbs == "function" && cbs(ctx.Share({"group": option.dataset.group, "name": option.dataset.name, "cmds": [
|
||||||
river, line.storm, line.action, args[1]||"",
|
river, line.storm, line.action, args[1]||"",
|
||||||
@ -347,12 +347,12 @@ var page = Page({check: true,
|
|||||||
},
|
},
|
||||||
_run: function() {
|
_run: function() {
|
||||||
var meta = plugin && plugin.target && plugin.target.Meta || {}
|
var meta = plugin && plugin.target && plugin.target.Meta || {}
|
||||||
field.Pane.Run([meta.river||river, meta.storm||storm, meta.action||index].concat(args), function(msg) {
|
field.Pane.Run([meta.river||river, meta.storm||storm, meta.action].concat(args), function(msg) {
|
||||||
engine._msg(msg), typeof cbs == "function" && cbs(msg)
|
engine._msg(msg), typeof cbs == "function" && cbs(msg)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if (args.length > 0 && engine[args[0]] && engine[args[0]](args)) {return}
|
if (args.length > 0 && engine[args[0]] && engine[args[0]](args)) {typeof cbs == "function" && cbs(line); return}
|
||||||
event.shiftKey? engine._msg(): engine._run()
|
event.shiftKey? engine._msg(): engine._run()
|
||||||
},
|
},
|
||||||
Show: function() {var pane = field.Pane
|
Show: function() {var pane = field.Pane
|
||||||
@ -469,12 +469,17 @@ var page = Page({check: true,
|
|||||||
"返回": function(event, value) {
|
"返回": function(event, value) {
|
||||||
page.plugin && page.plugin.Plugin.Last()
|
page.plugin && page.plugin.Plugin.Last()
|
||||||
},
|
},
|
||||||
|
"推送": function(event, value) {
|
||||||
|
if (page.socket) {return}
|
||||||
|
page.socket = page.WSS()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Button: [["layout", "聊天", "办公", "工作", "最高", "最宽", "最大"],
|
Button: [["layout", "聊天", "办公", "工作", "最高", "最宽", "最大"],
|
||||||
"", "刷新", "清屏", "并行", "串行",
|
"", "刷新", "清屏", "并行", "串行",
|
||||||
"", ["display", "表格", "编辑", "绘图"],
|
"", ["display", "表格", "编辑", "绘图"],
|
||||||
"", "添加", "删除", "加参", "减参",
|
"", "添加", "删除", "加参", "减参",
|
||||||
"", "执行", "下载", "清空", "返回",
|
"", "执行", "下载", "清空", "返回",
|
||||||
|
"", "推送",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -636,5 +641,6 @@ var page = Page({check: true,
|
|||||||
})
|
})
|
||||||
page.river.Pane.Show(), page.pane = page.action, page.plugin = kit.Selector(page.action, "fieldset")[0]
|
page.river.Pane.Show(), page.pane = page.action, page.plugin = kit.Selector(page.action, "fieldset")[0]
|
||||||
page.action.Pane.Layout(ctx.Search("layout")? ctx.Search("layout"): kit.device.isMobile? "办公": "工作")
|
page.action.Pane.Layout(ctx.Search("layout")? ctx.Search("layout"): kit.device.isMobile? "办公": "工作")
|
||||||
|
page.socket = page.WSS()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -204,6 +204,33 @@ ctx = context = {
|
|||||||
xhr.setRequestHeader("Accept", "application/json")
|
xhr.setRequestHeader("Accept", "application/json")
|
||||||
xhr.send(args.join("&"))
|
xhr.send(args.join("&"))
|
||||||
},
|
},
|
||||||
|
WSS: function(cb) {
|
||||||
|
var s = new WebSocket("ws://"+location.host+"/wss")
|
||||||
|
s.onopen = function(event) {
|
||||||
|
kit.Log(event)
|
||||||
|
}
|
||||||
|
s.onmessage = function(event) {
|
||||||
|
var msg = JSON.parse(event.data)
|
||||||
|
|
||||||
|
try {
|
||||||
|
var msg = JSON.parse(event.data||'{}')
|
||||||
|
} catch (e) {
|
||||||
|
var msg = {"result": [event.data]}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.event = event, msg.reply = function(sub) {
|
||||||
|
s.send(JSON.stringify(sub||msg))
|
||||||
|
}
|
||||||
|
typeof cb == "function" && cb(msg)
|
||||||
|
}
|
||||||
|
s.onerror = function(event) {
|
||||||
|
kit.Log(event)
|
||||||
|
}
|
||||||
|
s.onclose = function(event) {
|
||||||
|
kit.Log(event)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
},
|
||||||
Upload: function(file, cb, detail) {
|
Upload: function(file, cb, detail) {
|
||||||
var data = new FormData()
|
var data = new FormData()
|
||||||
data.append("upload", file)
|
data.append("upload", file)
|
||||||
|
@ -437,6 +437,17 @@ function Page(page) {
|
|||||||
}
|
}
|
||||||
return typeof page[args[0]] == "function" && kit._call(page[args[0]], args.slice(1))
|
return typeof page[args[0]] == "function" && kit._call(page[args[0]], args.slice(1))
|
||||||
},
|
},
|
||||||
|
WSS: function(cb) {
|
||||||
|
return ctx.WSS(cb || (function(m) {
|
||||||
|
if (m.detail) {
|
||||||
|
page.action.Pane.Core(event, m, ["_cmd", m.detail], function(msg) {
|
||||||
|
m.reply(msg)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
page.ontoast(m.result.join(""))
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
|
||||||
initToast: function() {},
|
initToast: function() {},
|
||||||
initLogin: function(page, field, option, output) {
|
initLogin: function(page, field, option, output) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user