From: qydysky Date: Tue, 2 Feb 2021 12:33:49 +0000 (+0800) Subject: websocket和简易web服务 X-Git-Tag: v0.3.9 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=35e8e7b2bbc1903912d5473739c98251d8b86918;p=part%2F.git websocket和简易web服务 --- diff --git a/README.md b/README.md index 730a022..1d899bc 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ - [github.com/klauspost/compress](https://github.com/klauspost/compress) under [BSD 3-Clause](https://raw.githubusercontent.com/klauspost/compress/master/LICENSE) - [github.com/andybalholm/brotli](https:github.com/andybalholm/brotli) under [MIT](https://raw.githubusercontent.com/andybalholm/brotli/master/LICENSE) - [github.com/klauspost/pgzip](https://github.com/klauspost/pgzip) under [MIT](https://raw.githubusercontent.com/klauspost/pgzip/master/LICENSE) +- [github.com/skratchdot/open-golang/open](https://github.com/skratchdot/open-golang) under [MIT](https://raw.githubusercontent.com/skratchdot/open-golang/master/LICENSE) +- [github.com/gorilla/websocket](https://github.com/gorilla/websocket) under [BSD 2-Clause](https://raw.githubusercontent.com/gorilla/websocket/master/LICENSE) --- #### 介绍 diff --git a/go.mod b/go.mod index 61032da..6a79f3f 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/klauspost/pgzip v1.2.5 github.com/miekg/dns v1.1.35 github.com/shirou/gopsutil v3.20.12+incompatible + github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/thedevsaddam/gojsonq v2.3.0+incompatible github.com/thedevsaddam/gojsonq/v2 v2.5.2 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect diff --git a/go.sum b/go.sum index 011911d..f67c4b2 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/shirou/gopsutil v2.20.7+incompatible h1:Ymv4OD12d6zm+2yONe39VSmp2XooJ github.com/shirou/gopsutil v2.20.7+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/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/thedevsaddam/gojsonq v1.9.1 h1:zQulEP43nwmq5EKrNWyIgJVbqDeMdC1qzXM/f5O15a0= github.com/thedevsaddam/gojsonq v2.3.0+incompatible h1:i2lFTvGY4LvoZ2VUzedsFlRiyaWcJm3Uh6cQ9+HyQA8= github.com/thedevsaddam/gojsonq v2.3.0+incompatible/go.mod h1:RBcQaITThgJAAYKH7FNp2onYodRz8URfsuEGpAch0NA= diff --git a/web/Web.go b/web/Web.go new file mode 100644 index 0000000..5accba5 --- /dev/null +++ b/web/Web.go @@ -0,0 +1,53 @@ +package part + +import ( + "net/http" + "time" + "strconv" + "context" + p "github.com/qydysky/part" +) + +type Web struct { + Server *http.Server + mux *http.ServeMux +} + +func New(conf *http.Server) (o *Web) { + + o = new(Web) + + o.Server = conf + + if o.Server.Addr == `` {o.Server.Addr = "127.0.0.1:"+strconv.Itoa(p.Sys().GetFreePort())} + if o.Server.WriteTimeout == 0 {o.Server.WriteTimeout = time.Second * time.Duration(10)} + if o.Server.Handler == nil { + o.mux = http.NewServeMux() + o.Server.Handler = o.mux + } + + go o.Server.ListenAndServe() + + return +} + +func (t *Web) Handle(path_func map[string]func(http.ResponseWriter,*http.Request)) { + for k,v := range path_func { + t.mux.HandleFunc(k,v) + } +} + +func Easy_boot() (*Web) { + s := New(&http.Server{}) + s.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, path) + }, + `/exit`:func(w http.ResponseWriter,r *http.Request){ + s.Server.Shutdown(context.Background()) + }, + }) + return s +} diff --git a/web/Web_test.go b/web/Web_test.go new file mode 100644 index 0000000..ec6f209 --- /dev/null +++ b/web/Web_test.go @@ -0,0 +1,12 @@ +package part + +import ( + "testing" + "time" +) + +func Test_Server(t *testing.T) { + s := Easy_boot() + t.Log(`http://`+s.Server.Addr) + time.Sleep(time.Second*time.Duration(100)) +} \ No newline at end of file diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..31200c9 --- /dev/null +++ b/web/index.html @@ -0,0 +1,11 @@ + + + + + + + + +

ok

+ + diff --git a/websocket/Server.go b/websocket/Server.go new file mode 100644 index 0000000..e02374e --- /dev/null +++ b/websocket/Server.go @@ -0,0 +1,126 @@ +package part + +import ( + "net" + "net/http" + "time" + "github.com/gorilla/websocket" + idpool "github.com/qydysky/part/idpool" + mq "github.com/qydysky/part/msgq" +) + +type Server struct { + ws_mq *mq.Msgq + userpool *idpool.Idpool +} + +type Uinterface struct { + Id uintptr + Data []byte +} + +func New_server() (*Server) { + return &Server{ + ws_mq: mq.New(200),//收发通道 + userpool: idpool.New(),//浏览器标签页池 + } +} + +func (t *Server) WS(w http.ResponseWriter, r *http.Request) { + upgrader := websocket.Upgrader{} + + ws, err := upgrader.Upgrade(w, r, nil) + if err != nil { + t.ws_mq.Push_tag(`error`,err) + return + } + defer ws.Close() + + //从池中获取本会话id + User := t.userpool.Get() + defer t.userpool.Put(User) + + + //发送 + t.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 == User.Id{ + if err := ws.WriteMessage(websocket.TextMessage,u.Data);err != nil { + t.ws_mq.Push_tag(`error`,err) + return true + } + } + return false + }, + `close`:func(data interface{})(bool){ + if u,ok := data.(Uinterface);ok && u.Id == 0 || u.Id == User.Id{ + return true + } + return false + }, + }) + + //接收 + for { + ws.SetReadDeadline(time.Now().Add(time.Second*time.Duration(300))) + if _, message, err := ws.ReadMessage();err != nil { + if websocket.IsCloseError(err,websocket.CloseGoingAway) { + } else if err,ok := err.(net.Error);ok && err.Timeout() { + //Timeout , js will reload html + } else { + t.ws_mq.Push_tag(`error`,err) + } + t.ws_mq.Push_tag(`close`,Uinterface{ + Id:User.Id, + }) + break + } else { + t.ws_mq.Push_tag(`recv`,Uinterface{ + Id:User.Id, + Data:message, + }) + } + } +} + +//how to use +// ws_mq.Pull_tag(map[string]func(interface{})(bool){ +// `recv`:func(data interface{})(bool){ +// if tmp,ok := data.(Uinterface);ok { +// log.Println(tmp.Id,string(tmp.Data)) + +// if string(tmp.Data) == `close` { +// ws_mq.Push_tag(`close`,Uinterface{//close +// Id:0,//close all connect +// }) +// //or +// // ws_mq.Push_tag(`close`,Uinterface{//close +// // Id:tmp.Id,//close this connect +// // }) +// return false +// } + +// ws_mq.Push_tag(`send`,Uinterface{//just reply +// Id:tmp.Id, +// Data:tmp.Data, +// }) +// //or +// ws_mq.Push_tag(`send`,Uinterface{//just reply +// Id:0,//send to all +// Data:tmp.Data, +// }) +// } +// return false +// }, +// `error`:func(data interface{})(bool){ +// log.Println(data) +// return false +// }, +// }) +func (t *Server) Interface() (*mq.Msgq) { + return t.ws_mq +} + +func (t *Server) Len() uint { + return t.userpool.Len() +} \ No newline at end of file diff --git a/websocket/Server_test.go b/websocket/Server_test.go new file mode 100644 index 0000000..fcf1743 --- /dev/null +++ b/websocket/Server_test.go @@ -0,0 +1,37 @@ +package part + +import ( + "testing" + "net/http" + "time" + "github.com/skratchdot/open-golang/open" + web "github.com/qydysky/part/web" +) + +func Test_Server(t *testing.T) { + s := New_server() + { + ws_mq := s.Interface() + ws_mq.Pull_tag(map[string]func(interface{})(bool){ + `recv`:func(data interface{})(bool){ + if tmp,ok := data.(Uinterface);ok { + t.Log(tmp.Id,string(tmp.Data)) + ws_mq.Push_tag(`send`,Uinterface{//just reply + Id:tmp.Id, + Data:tmp.Data, + }) + } + return false + }, + }) + } + + w := web.Easy_boot() + open.Run("http://"+w.Server.Addr) + w.Handle(map[string]func(http.ResponseWriter,*http.Request){ + `/ws`:func(w http.ResponseWriter,r *http.Request){ + s.WS(w,r) + }, + }) + time.Sleep(time.Second*time.Duration(100)) +} \ No newline at end of file diff --git a/websocket/index.html b/websocket/index.html new file mode 100644 index 0000000..5a42ca7 --- /dev/null +++ b/websocket/index.html @@ -0,0 +1,30 @@ + + + + + + + + +

websocket

+

+ + +