package F
import (
- "net"
"net/http"
"encoding/json"
"time"
- "context"
- "sync"
- "strconv"
- "github.com/gorilla/websocket"
"github.com/skratchdot/open-golang/open"
- p "github.com/qydysky/part"
- mq "github.com/qydysky/part/msgq"
+ websocket "github.com/qydysky/part/websocket"
+ web "github.com/qydysky/part/web"
c "github.com/qydysky/bili_danmu/CV"
)
//返回的加密对象
type S struct {
+ Id string `json:"id"`//发送的数据中的Id项,以确保是对应的返回
S string `json:"s"` //加密字符串
}
-type Uinterface struct {
- Id uint
- Data interface{}
- sync.Mutex
-}
//全局对象
var (
- xinxinboot = make(chan struct{},1) //调用标记,仅调用一次
wslog = c.Log.Base(`api`).Base_add(`小心心加密`) //日志
- rec_chan = make(chan S,1)//收通道
- ws_mq = mq.New(200)//发通道
- port = p.Sys().GetFreePort()//随机端口
+ rec_chan = make(chan S)//收通道
+ webpath string//web地址,由于实时获取空闲端口,故将在稍后web启动后赋值
+ ws = websocket.New_server()//新建websocket实例
)
func init() {
break
}
- wslog.L(`T: `,`被调用`)
-
- select{
- case xinxinboot <- struct{}{}: //没有启动实例
- wslog.L(`I: `,`启动`)
- web()
- <- xinxinboot
- default: //有启动实例
- wslog.L(`I: `,`已启动`)
- }
+ //初始化web服务器,初始化websocket
+ server()
+ wslog.L(`I: `,`启动`)
}()
}
-func web() {
- web := http.NewServeMux()
-
- var (
- server *http.Server
- upgrader = websocket.Upgrader{}
- id = Uinterface{
- Id:1,//0表示全局广播
- }
- )
-
- web.HandleFunc("/exit", func(w http.ResponseWriter, r *http.Request) {
- server.Shutdown(context.Background())
- })
-
- web.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
- ws, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- wslog.L(`E: `,"upgrade:", err)
- return
- }
- defer ws.Close()
-
- //本会话id
- Uid := id.Id
- id.Lock()
- id.Id += 1
- id.Unlock()
-
- //测试 提示
- go test(Uid)
-
- //发送
+func server() {
+ {
+ ws_mq := ws.Interface()//获取websocket操作对象
ws_mq.Pull_tag(map[string]func(interface{})(bool){
- `send`:func(data interface{})(bool){
- if u,ok := data.(Uinterface);ok && u.Id == 0 || u.Id == Uid{
- if t,ok := u.Data.(RT);ok {
- b, e := json.Marshal(t)
- if e != nil {
- wslog.L(`E: `,e)
- }
-
- if e := ws.WriteMessage(websocket.TextMessage,b);e != nil {
- wslog.L(`E: `,e)
- return true
- }
+ `recv`:func(data interface{})(bool){
+ if tmp,ok := data.(websocket.Uinterface);ok {//websocket接收并响应
+ //websocket.Uinterface{
+ // Id uintptr 会话id
+ // Data []byte 接收的websocket数据
+ // }
+
+ var s S
+ e := json.Unmarshal(tmp.Data, &s)
+ if e != nil {
+ wslog.L(`E: `, e, string(tmp.Data))
}
+
+ select{//无多用户上传不同数据的情况,仅接收1个,其余会因通道无传出而忽略
+ case rec_chan <- s:
+ default:
+ }
+
}
return false
},
- `close`:func(data interface{})(bool){
- if u,ok := data.(Uinterface);ok && u.Id == 0 || u.Id == Uid{
- return true
- }
+ `error`:func(data interface{})(bool){//websocket错误
+ wslog.L(`E: `,data)
return false
},
})
+ }
- //接收
- for {
- ws.SetReadDeadline(time.Now().Add(time.Second*time.Duration(300)))
- if _, message, e := ws.ReadMessage();e != nil {
- if websocket.IsCloseError(e,websocket.CloseGoingAway) {
- wslog.L(`I: `,e)
- } else if e,ok := e.(net.Error);ok && e.Timeout() {
- //Timeout , js will reload html
- } else {
- wslog.L(`E: `,e)
- }
- ws_mq.Push_tag(`close`,Uinterface{
- Id:Uid,
- })
- break
- } else {
- var s S
- e := json.Unmarshal(message, &s)
- if e != nil {
- wslog.L(`E: `, e, string(message))
- }
-
- select{//现阶段暂不考虑多用户上传不同数据的情况
- case rec_chan <- s:
- default:
- }
- }
- }
+ w := web.New(&http.Server{})//新建web实例
+ w.Handle(map[string]func(http.ResponseWriter,*http.Request){//路径处理函数
+ `/`:func(w http.ResponseWriter,r *http.Request){
+ var path string = r.URL.Path[1:]
+ if path == `` {path = `index.html`}
+ http.ServeFile(w, r, "html/"+path)
+ },
+ `/ws`:func(w http.ResponseWriter,r *http.Request){
+ //获取通道
+ conn := ws.WS(w,r)
+ //由通道获取本次会话id,并测试 提示
+ go test(<-conn)
+ //等待会话结束,通道释放
+ <-conn
+ },
})
+ webpath = `http://`+w.Server.Addr
+ //提示
+ wslog.L(`I: `,`如需加密,会自动打开`,webpath)
+}
- //html js
- web.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- var path string = r.URL.Path[1:]
- if path == `` {path = `index.html`}
- http.ServeFile(w, r, "html/"+path)
- })
-
- server = &http.Server{
- Addr: "127.0.0.1:"+strconv.Itoa(port),
- WriteTimeout: time.Second * time.Duration(10),
- Handler: web,
+func Wasm(uid uintptr,s RT) (o string) {
+ for try:=5;try > 0 && ws.Len() == 0;try-=1 {//没有从池中取出
+ open.Run(webpath)
+ wslog.L(`I: `,`浏览器打开`,webpath)
+ time.Sleep(time.Second)
}
- //测试 提示
- go func(){
- time.Sleep(time.Second*time.Duration(3))
- open.Run("http://127.0.0.1:"+strconv.Itoa(port))
- wslog.L(`I: `,`保持浏览器打开`,"http://127.0.0.1:"+strconv.Itoa(port),`以正常运行`)
- }()
-
- server.ListenAndServe()
-}
+ b, e := json.Marshal(s)
+ if e != nil {
+ wslog.L(`E: `,e)
+ }
-func Wasm(uid uint,s RT) (o string) {
- ws_mq.Push_tag(`send`,Uinterface{
+ //获取websocket操作对象 发送
+ ws.Interface().Push_tag(`send`,websocket.Uinterface{
Id:uid,
- Data:s,
+ Data:b,
})
- select {
- case r :=<- rec_chan:
- return r.S
- case <- time.After(time.Second):
- wslog.L(`E: `,`超时!响应>1s,确认保持`,"http://127.0.0.1:"+strconv.Itoa(port),`开启`)
- return
+ for {
+ select {
+ case r :=<- rec_chan:
+ if r.Id != s.R.Id {break}//或许接收到之前的请求,校验Id字段
+ return r.S
+ case <- time.After(time.Second):
+ wslog.L(`E: `,`超时!响应>1s,确认保持`,webpath,`开启`)
+ return
+ }
}
}
-func test(uid uint) bool {
+func test(uid uintptr) bool {
time.Sleep(time.Second*time.Duration(3))
if s := Wasm(uid, RT{
R:R{
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs=
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
+github.com/miekg/dns v1.1.38 h1:MtIY+fmHUVVgv1AXzmKMWcwdCYxTRPG1EDjpqF4RCEw=
+github.com/miekg/dns v1.1.38/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
github.com/qydysky/part v0.3.5-0.20210115055155-7961661607d9/go.mod h1:zE9KPP+RD3EQ4wYL14szrB927AU3amyha/2wKPjPWzo=
github.com/qydysky/part v0.3.6 h1:KKmNAhF9VtON5p3AH5ohMjrIwGv1lJKrGqmNwYYxFU0=
github.com/qydysky/part v0.3.6/go.mod h1:zE9KPP+RD3EQ4wYL14szrB927AU3amyha/2wKPjPWzo=
+github.com/qydysky/part v0.3.7 h1:6VkyOHtAfUXtt4QArZBdEnsMzcoungn6BW3wvmwJF8Q=
+github.com/qydysky/part v0.3.7/go.mod h1:zE9KPP+RD3EQ4wYL14szrB927AU3amyha/2wKPjPWzo=
+github.com/qydysky/part v0.3.8 h1:KG92F9FA9+NoLLOGCHAYuxcgZtNjVFZphvKPOzpotm8=
+github.com/qydysky/part v0.3.8/go.mod h1:zE9KPP+RD3EQ4wYL14szrB927AU3amyha/2wKPjPWzo=
+github.com/qydysky/part v0.3.9 h1:eX/n+839mwX5vRDHtmO3jU0eIQJynE8wmEqCZN7xMZM=
+github.com/qydysky/part v0.3.9/go.mod h1:43opuciW71sZvOR67kye50jgMDSDrn/t6+LefNdlXPg=
+github.com/qydysky/part v0.3.10 h1:hb6HcedujeqfKWmV1r30Wu9JYcajS0cM4bLFco63bIY=
+github.com/qydysky/part v0.3.10/go.mod h1:43opuciW71sZvOR67kye50jgMDSDrn/t6+LefNdlXPg=
github.com/qydysky/part/msgq v0.0.0-20201213031129-ca3253dc72ad h1:Jtzf509lQrkUMGTV0Sc6IDCAiR1VrBcHrIban7hpye4=
github.com/qydysky/part/msgq v0.0.0-20201213031129-ca3253dc72ad/go.mod h1:w32TkJNVtTJd4LOS09cq+4uYG6itcN2vsqw+slp44Rg=
github.com/qydysky/part/msgq v0.0.0-20201213120821-f36e49c32bba h1:1ew9dRpc0Rux0WkWeT/4AE15ynYWmL2D7onJEJIFOB8=
github.com/shirou/gopsutil v3.20.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.20.12+incompatible h1:6VEGkOXP/eP4o2Ilk8cSsX0PhOEfX6leqAnD+urrp9M=
github.com/shirou/gopsutil v3.20.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
+github.com/shirou/gopsutil v3.21.1+incompatible h1:2LwXWdbjXwyDgq26Yy/OT4xozlpmssQfy/rtfhWb0bY=
+github.com/shirou/gopsutil v3.21.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=