1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00

add web.wss

This commit is contained in:
shaoying 2019-09-22 15:51:04 +08:00
parent 16f7cde6bb
commit 78be157b5d
10 changed files with 188 additions and 7 deletions

View File

@ -4,5 +4,5 @@ var version = struct {
host string
self int
}{
"2019-09-22 09:30:17", "mac", 632,
"2019-09-22 15:44:02", "mac", 660,
}

View File

@ -1,10 +1,10 @@
package ctx
import (
"runtime"
"errors"
"fmt"
"io"
"runtime"
"strings"
"time"
"toolkit"
@ -382,7 +382,10 @@ func (m *Message) Call(cb func(msg *Message) (sub *Message), arg ...interface{})
if m == nil {
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.Cmd(arg...)
}

View File

@ -70,6 +70,7 @@ type Message struct {
Hand bool
Meta map[string][]string
Data map[string]interface{}
Sync chan bool
callback func(msg *Message) (sub *Message)
freeback []func(msg *Message) (done bool)

View File

@ -1,6 +1,7 @@
package web
import (
"github.com/gorilla/websocket"
"github.com/skip2/go-qrcode"
"contexts/ctx"
@ -119,7 +120,8 @@ func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request)
return false
}
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: "/"})
}
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{}{
"time": map[string]interface{}{"cmd": "time"},
}, Help: "工具列表"},
"wss": &ctx.Config{Name: "wss", Value: map[string]interface{}{}, Help: ""},
},
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) {
@ -1081,6 +1084,122 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
})
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
}},
},
}

View File

@ -195,6 +195,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
if !m.Options("sessid") || !m.Options("username") {
return
}
m.Short("river")
// 自动入群
if m.Options("river") {

View File

@ -48,3 +48,10 @@ fun media "娱乐" private \
end
end
kit wss "推送" private "web.wss" \
text "" name wss imports plugin_wss \
text "" name cmd \
button "推送" \
button "返回" click Last \
exports wss key

View File

@ -317,6 +317,12 @@ func Map(v interface{}, random string, args ...interface{}) map[string]interface
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{}):
switch random {
case "%":

View File

@ -280,7 +280,7 @@ var page = Page({check: true,
], 0)
},
Core: function(event, line, args, cbs) {
var plugin = event.Plugin || {}, engine = {
var plugin = event.Plugin || page.plugin && page.plugin.Plugin || {}, engine = {
share: function(args) {
typeof cbs == "function" && cbs(ctx.Share({"group": option.dataset.group, "name": option.dataset.name, "cmds": [
river, line.storm, line.action, args[1]||"",
@ -347,12 +347,12 @@ var page = Page({check: true,
},
_run: function() {
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)
})
},
}
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()
},
Show: function() {var pane = field.Pane
@ -469,12 +469,17 @@ var page = Page({check: true,
"返回": function(event, value) {
page.plugin && page.plugin.Plugin.Last()
},
"推送": function(event, value) {
if (page.socket) {return}
page.socket = page.WSS()
},
},
Button: [["layout", "聊天", "办公", "工作", "最高", "最宽", "最大"],
"", "刷新", "清屏", "并行", "串行",
"", ["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.action.Pane.Layout(ctx.Search("layout")? ctx.Search("layout"): kit.device.isMobile? "办公": "工作")
page.socket = page.WSS()
},
})

View File

@ -204,6 +204,33 @@ ctx = context = {
xhr.setRequestHeader("Accept", "application/json")
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) {
var data = new FormData()
data.append("upload", file)

View File

@ -437,6 +437,17 @@ function Page(page) {
}
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() {},
initLogin: function(page, field, option, output) {