File tree Expand file tree Collapse file tree 7 files changed +190
-1
lines changed Expand file tree Collapse file tree 7 files changed +190
-1
lines changed Original file line number Diff line number Diff line change 1+ package main
2+
3+ import "github.com/gorilla/websocket"
4+
5+ type connection struct {
6+ ws * websocket.Conn
7+ send chan []byte
8+ hub * hub
9+ }
10+
11+ func newConnection (ws * websocket.Conn , hub * hub ) connection {
12+ return connection {
13+ ws : ws ,
14+ send : make (chan []byte , 256 ),
15+ hub : hub ,
16+ }
17+ }
18+
19+ func (c * connection ) read () {
20+ for {
21+ _ , message , err := c .ws .ReadMessage ()
22+ if err != nil {
23+ break
24+ }
25+
26+ c .hub .broadcast <- message
27+ }
28+ c .ws .Close ()
29+ }
30+
31+ func (c * connection ) write () {
32+ for message := range c .send {
33+ if err := c .ws .WriteMessage (websocket .TextMessage , message ); err != nil {
34+ break
35+ }
36+ }
37+ c .ws .Close ()
38+ }
Original file line number Diff line number Diff line change 1- module github.com/Lapp-coder/websocket-server
1+ module github.com/Lapp-coder/websocket-chat
22
33go 1.16
4+
5+ require (
6+ github.com/gorilla/websocket v1.4.2
7+ github.com/sirupsen/logrus v1.8.1
8+ )
Original file line number Diff line number Diff line change 1+ github.com/davecgh/go-spew v1.1.1 /go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38 =
12github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc =
23github.com/gorilla/websocket v1.4.2 /go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE =
4+ github.com/pmezard/go-difflib v1.0.0 /go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4 =
5+ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE =
6+ github.com/sirupsen/logrus v1.8.1 /go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0 =
7+ github.com/stretchr/testify v1.2.2 /go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs =
8+ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4 =
9+ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 /go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs =
Original file line number Diff line number Diff line change 1+ package main
2+
3+ import (
4+ "fmt"
5+ "github.com/gorilla/websocket"
6+ "net/http"
7+ )
8+
9+ var upgrader = websocket.Upgrader {
10+ ReadBufferSize : 1024 ,
11+ WriteBufferSize : 1024 ,
12+ }
13+
14+ type handler struct {
15+ hub * hub
16+ }
17+
18+ func newHandler (hub * hub ) * handler {
19+ return & handler {hub : hub }
20+ }
21+
22+ func (h * handler ) initRoutes () {
23+ http .HandleFunc ("/" , h .index )
24+ http .HandleFunc ("/chat" , h .chat )
25+ }
26+
27+ func (h * handler ) index (w http.ResponseWriter , r * http.Request ) {
28+ fmt .Fprint (w , "<h1>Chat on websockets</h1>" )
29+ }
30+
31+ func (h * handler ) chat (w http.ResponseWriter , r * http.Request ) {
32+ ws , err := upgrader .Upgrade (w , r , nil )
33+ if err != nil {
34+ return
35+ }
36+
37+ conn := newConnection (ws , h .hub )
38+ conn .hub .register <- & conn
39+ defer func () {
40+ conn .hub .unregister <- & conn
41+ }()
42+
43+ go conn .write ()
44+ conn .read ()
45+ }
Original file line number Diff line number Diff line change 1+ package main
2+
3+ type hub struct {
4+ connections map [* connection ]struct {}
5+ broadcast chan []byte
6+ register chan * connection
7+ unregister chan * connection
8+ }
9+
10+ func newHub () hub {
11+ return hub {
12+ connections : make (map [* connection ]struct {}),
13+ broadcast : make (chan []byte ),
14+ register : make (chan * connection ),
15+ unregister : make (chan * connection ),
16+ }
17+ }
18+
19+ func (h * hub ) run () {
20+ for {
21+ select {
22+ case conn := <- h .register :
23+ h .connections [conn ] = struct {}{}
24+ case conn := <- h .unregister :
25+ if _ , ok := h .connections [conn ]; ok {
26+ delete (h .connections , conn )
27+ close (conn .send )
28+ }
29+ case message := <- h .broadcast :
30+ for conn := range h .connections {
31+ conn .send <- message
32+ }
33+ }
34+ }
35+ }
Original file line number Diff line number Diff line change 11package main
22
3+ import (
4+ "context"
5+ "github.com/sirupsen/logrus"
6+ "os"
7+ "os/signal"
8+ "syscall"
9+ )
10+
311func main () {
12+ hub := newHub ()
13+ handler := newHandler (& hub )
14+ handler .initRoutes ()
15+ go hub .run ()
16+
17+ host := os .Getenv ("CHAT_HOST" )
18+ port := os .Getenv ("CHAT_PORT" )
19+ srv := newServer (host , port )
20+
21+ go func () {
22+ if err := srv .start (); err != nil {
23+ logrus .Errorf ("failed to start server: %s" , err .Error ())
24+ }
25+ }()
26+
27+ logrus .Info ("server started" )
28+
29+ shutdown := make (chan os.Signal )
30+ signal .Notify (shutdown , syscall .SIGINT , syscall .SIGTERM )
31+ <- shutdown
32+
33+ logrus .Info ("server shutdown" )
434
35+ if err := srv .shutdown (context .Background ()); err != nil {
36+ logrus .Errorf ("failed to graceful shutdown server: %s" , err .Error ())
37+ }
538}
Original file line number Diff line number Diff line change 1+ package main
2+
3+ import (
4+ "context"
5+ "net/http"
6+ )
7+
8+ type server struct {
9+ httpServer * http.Server
10+ }
11+
12+ func newServer (host , port string ) * server {
13+ return & server {
14+ httpServer : & http.Server {
15+ Addr : host + ":" + port ,
16+ },
17+ }
18+ }
19+
20+ func (s * server ) start () error {
21+ return s .httpServer .ListenAndServe ()
22+ }
23+
24+ func (s * server ) shutdown (ctx context.Context ) error {
25+ return s .httpServer .Shutdown (ctx )
26+ }
You can’t perform that action at this time.
0 commit comments