Bläddra i källkod

add implementation with server sent events

Gildas Chabot 6 år sedan
förälder
incheckning
583ae2ce4e
2 ändrade filer med 69 tillägg och 11 borttagningar
  1. 22 2
      index.html
  2. 47 9
      ms.go

+ 22 - 2
index.html

@@ -8,17 +8,37 @@
8 8
           <button onclick="websocket()">Listen</button>
9 9
       </div>
10 10
 
11
+      <div>
12
+          <h2>Server Sent Event</h2>
13
+          <p>Progress: <span id="sse"></span></p>
14
+          <button onclick="sse()">Listen</button>
15
+      </div>
16
+
11 17
       <script>
12 18
        function websocket() {
13 19
          var socket = new WebSocket({{ .websocket }}, "protocolOne");
14 20
          socket.onmessage = function (event) {
15
-           if (event.data === "done") {
21
+           if (event.data === "100") {
16 22
              document.getElementById("websocket").innerHTML = "done!";
17 23
              socket.close();
18 24
              return;
19 25
            }
20 26
            document.getElementById("websocket").innerHTML=event.data+"%";
21
-         }
27
+         };
28
+       }
29
+
30
+       function sse() {
31
+         document.getElementById("sse").innerHTML = "done!";
32
+         var source = new EventSource({{ .sse }});
33
+         source.onmessage = function(event) {
34
+           console.log("truc");
35
+           if (event.data === "100") {
36
+             document.getElementById("sse").innerHTML = "done!";
37
+             source.close();
38
+             return;
39
+           }
40
+           document.getElementById("sse").innerHTML=event.data+"%";
41
+         };
22 42
        }
23 43
       </script>
24 44
   </body>

+ 47 - 9
ms.go

@@ -1,6 +1,7 @@
1 1
 package main
2 2
 
3 3
 import (
4
+	"io"
4 5
 	"math/rand"
5 6
 	"net/http"
6 7
 	"os"
@@ -26,11 +27,13 @@ func main() {
26 27
 	router.GET("/", func(c *gin.Context) {
27 28
 		c.HTML(http.StatusOK, "index.html", gin.H{
28 29
 			"websocket": "ws://localhost:" + port + "/ws",
30
+			"sse":       "http://localhost:" + port + "/sse",
29 31
 		})
30 32
 	})
31 33
 	router.GET("/ws", websocketHandler(websocket.Upgrader{
32 34
 		Subprotocols: []string{"protocolOne"},
33 35
 	}))
36
+	router.GET("/sse", serverSentEventHandler())
34 37
 
35 38
 	router.Run(":" + port)
36 39
 }
@@ -43,20 +46,55 @@ func websocketHandler(upgrader websocket.Upgrader) func(c *gin.Context) {
43 46
 			return
44 47
 		}
45 48
 
46
-		progress := 0
47
-		for progress < 100 {
49
+		t := task{}
50
+		t.start()
51
+		for {
52
+			progress, ok := <-t.progress
53
+			if !ok {
54
+				break
55
+			}
56
+
48 57
 			if err := conn.WriteMessage(1, []byte(strconv.Itoa(progress))); err != nil {
49 58
 				c.AbortWithError(http.StatusInternalServerError, err)
50 59
 				return
51 60
 			}
52
-
53
-			progress += rand.Intn(2)
54
-			time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
55 61
 		}
62
+	}
63
+}
56 64
 
57
-		if err := conn.WriteMessage(1, []byte("done")); err != nil {
58
-			c.AbortWithError(http.StatusInternalServerError, err)
59
-			return
60
-		}
65
+func serverSentEventHandler() func(c *gin.Context) {
66
+	return func(c *gin.Context) {
67
+		t := task{}
68
+		t.start()
69
+
70
+		c.Stream(func(w io.Writer) bool {
71
+			progress, ok := <-t.progress
72
+			if !ok {
73
+				return false
74
+			}
75
+
76
+			c.SSEvent("", strconv.Itoa(progress))
77
+			return true
78
+		})
61 79
 	}
62 80
 }
81
+
82
+type task struct {
83
+	progress chan int
84
+}
85
+
86
+func (t *task) start() {
87
+	t.progress = make(chan int)
88
+	go func() {
89
+		p := 0
90
+		t.progress <- p
91
+		for p < 100 {
92
+			if rand.Intn(100) > 50 {
93
+				p++
94
+				t.progress <- p
95
+			}
96
+			time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
97
+		}
98
+		close(t.progress)
99
+	}()
100
+}