diff --git a/QR.png b/QR.png new file mode 100644 index 0000000..e0540c7 Binary files /dev/null and b/QR.png differ diff --git a/go.mod b/go.mod index 29e985d..d2e52fc 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,9 @@ require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-gonic/gin v1.9.1 github.com/go-ini/ini v1.67.0 + github.com/gorilla/websocket v1.5.1 github.com/jinzhu/gorm v1.9.16 - golang.org/x/crypto v0.9.0 + golang.org/x/crypto v0.14.0 ) require ( @@ -31,9 +32,9 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2f30501..fd2d718 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -89,24 +91,24 @@ golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/handlers/ClientManager.go b/handlers/ClientManager.go new file mode 100644 index 0000000..ab36434 --- /dev/null +++ b/handlers/ClientManager.go @@ -0,0 +1,113 @@ +// Package ws is to define a websocket server and client connect. +// Author: Arthur Zhang +// Create Date: 20190101 +package handlers + +import ( + "encoding/json" + + "github.com/gorilla/websocket" +) + +// ClientManager is a websocket manager +type ClientManager struct { + Clients map[*Client]bool + Broadcast chan []byte + Register chan *Client + Unregister chan *Client +} + +// Client is a websocket client +type Client struct { + ID string + Socket *websocket.Conn + Send chan []byte +} + +// Message is an object for websocket message which is mapped to json type +type Message struct { + Sender string `json:"sender,omitempty"` + Recipient string `json:"recipient,omitempty"` + Content string `json:"content,omitempty"` +} + +// Manager define a ws server manager +var Manager = ClientManager{ + Broadcast: make(chan []byte), + Register: make(chan *Client), + Unregister: make(chan *Client), + Clients: make(map[*Client]bool), +} + +// Start is to start a ws server +func (manager *ClientManager) Start() { + for { + select { + case conn := <-manager.Register: + manager.Clients[conn] = true + jsonMessage, _ := json.Marshal(&Message{Content: "/A new socket has connected."}) + manager.Send(jsonMessage, conn) + case conn := <-manager.Unregister: + if _, ok := manager.Clients[conn]; ok { + close(conn.Send) + delete(manager.Clients, conn) + jsonMessage, _ := json.Marshal(&Message{Content: "/A socket has disconnected."}) + manager.Send(jsonMessage, conn) + } + case message := <-manager.Broadcast: + for conn := range manager.Clients { + select { + case conn.Send <- message: + default: + close(conn.Send) + delete(manager.Clients, conn) + } + } + } + } +} + +// Send is to send ws message to ws client +func (manager *ClientManager) Send(message []byte, ignore *Client) { + for conn := range manager.Clients { + if conn != ignore { + conn.Send <- message + } + } +} + +func (c *Client) Read() { + defer func() { + Manager.Unregister <- c + c.Socket.Close() + }() + + for { + _, message, err := c.Socket.ReadMessage() + if err != nil { + Manager.Unregister <- c + c.Socket.Close() + break + } + jsonMessage, _ := json.Marshal(&Message{Sender: c.ID, Content: string(message)}) + Manager.Broadcast <- jsonMessage + } +} + +func (c *Client) Write() { + defer func() { + c.Socket.Close() + }() + + for { + select { + case message, ok := <-c.Send: + if !ok { + c.Socket.WriteMessage(websocket.CloseMessage, []byte{}) + return + } + + c.Socket.WriteMessage(websocket.TextMessage, message) + } + } +} diff --git a/main.go b/main.go index c37051f..52d4adc 100644 --- a/main.go +++ b/main.go @@ -2,11 +2,14 @@ package main import ( "flag" + "fmt" "go_blog/conf" "go_blog/handlers" "go_blog/models" + "net/http" "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" ) type UserInfo struct { @@ -63,6 +66,43 @@ func main() { }) }) + // 注册WebSocket路由 + r.GET("/ws", WebSocketHandler) + r.POST("/login", handlers.UsersLoginHandler) r.Run(":8080") } + +func WebSocketHandler(c *gin.Context) { + // 获取WebSocket连接 + //ws, err := websocket.Upgrader.Upgrade(c.Writer, c.Request, nil) + + var upGrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true + }, + } + + ws, err := upGrader.Upgrade(c.Writer, c.Request, nil) + + if err != nil { + panic(err) + } + + // 处理WebSocket消息 + for { + messageType, p, err := ws.ReadMessage() + if err != nil { + break + } + + fmt.Println("messageType:", messageType) + fmt.Println("p:", string(p)) + + // 输出WebSocket消息内容 + c.Writer.Write(p) + } + + // 关闭WebSocket连接 + ws.Close() +} diff --git a/templates/list.tmpl b/templates/list.tmpl new file mode 100644 index 0000000..74f3499 --- /dev/null +++ b/templates/list.tmpl @@ -0,0 +1,43 @@ + + +
+