Browse Source

Adds realtime-chat example code

Manu Mtz-Almeida 10 years ago
parent
commit
15b0c49da5
3 changed files with 135 additions and 0 deletions
  1. 58 0
      examples/realtime-chat/main.go
  2. 33 0
      examples/realtime-chat/rooms.go
  3. 44 0
      examples/realtime-chat/template.go

+ 58 - 0
examples/realtime-chat/main.go

@@ -0,0 +1,58 @@
+package main
+
+import (
+	"fmt"
+	"io"
+	"math/rand"
+
+	"github.com/gin-gonic/gin"
+)
+
+func main() {
+	router := gin.Default()
+	router.SetHTMLTemplate(html)
+
+	router.GET("/room/:roomid", roomGET)
+	router.POST("/room/:roomid", roomPOST)
+	router.DELETE("/room/:roomid", roomDELETE)
+	router.GET("/stream/:roomid", stream)
+
+	router.Run(":8080")
+}
+
+func stream(c *gin.Context) {
+	roomid := c.ParamValue("roomid")
+	listener := openListener(roomid)
+	defer closeListener(roomid, listener)
+
+	c.Stream(func(w io.Writer) bool {
+		c.SSEvent("message", <-listener)
+		return true
+	})
+}
+
+func roomGET(c *gin.Context) {
+	roomid := c.ParamValue("roomid")
+	userid := fmt.Sprint(rand.Int31())
+	c.HTML(200, "chat_room", gin.H{
+		"roomid": roomid,
+		"userid": userid,
+	})
+}
+
+func roomPOST(c *gin.Context) {
+	roomid := c.ParamValue("roomid")
+	userid := c.PostFormValue("user")
+	message := c.PostFormValue("message")
+	room(roomid).Submit(userid + ": " + message)
+
+	c.JSON(200, gin.H{
+		"status":  "success",
+		"message": message,
+	})
+}
+
+func roomDELETE(c *gin.Context) {
+	roomid := c.ParamValue("roomid")
+	deleteBroadcast(roomid)
+}

+ 33 - 0
examples/realtime-chat/rooms.go

@@ -0,0 +1,33 @@
+package main
+
+import "github.com/dustin/go-broadcast"
+
+var roomChannels = make(map[string]broadcast.Broadcaster)
+
+func openListener(roomid string) chan interface{} {
+	listener := make(chan interface{})
+	room(roomid).Register(listener)
+	return listener
+}
+
+func closeListener(roomid string, listener chan interface{}) {
+	room(roomid).Unregister(listener)
+	close(listener)
+}
+
+func deleteBroadcast(roomid string) {
+	b, ok := roomChannels[roomid]
+	if ok {
+		b.Close()
+		delete(roomChannels, roomid)
+	}
+}
+
+func room(roomid string) broadcast.Broadcaster {
+	b, ok := roomChannels[roomid]
+	if !ok {
+		b = broadcast.NewBroadcaster(10)
+		roomChannels[roomid] = b
+	}
+	return b
+}

+ 44 - 0
examples/realtime-chat/template.go

@@ -0,0 +1,44 @@
+package main
+
+import "html/template"
+
+var html = template.Must(template.New("chat_room").Parse(`
+<html> 
+<head> 
+    <title>{{.roomid}}</title>
+    <link rel="stylesheet" type="text/css" href="http://meyerweb.com/eric/tools/css/reset/reset.css"/>
+    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script> 
+    <script src="http://malsup.github.com/jquery.form.js"></script> 
+    <script> 
+        $('#message_form').focus();
+        $(document).ready(function() { 
+            // bind 'myForm' and provide a simple callback function 
+            $('#myForm').ajaxForm(function() {
+                $('#message_form').val('');
+                $('#message_form').focus();
+            });
+
+            if (!!window.EventSource) {
+                var source = new EventSource('/stream/{{.roomid}}');
+                source.addEventListener('message', function(e) {
+                    $('#messages').append(e.data + "</br>");
+                    $('html, body').animate({scrollTop:$(document).height()}, 'slow');
+
+                }, false);
+            } else {
+                alert("NOT SUPPORTED");
+            }
+        });
+    </script> 
+    </head>
+    <body>
+    <h1>Welcome to {{.roomid}} room</h1>
+    <div id="messages"></div>
+    <form id="myForm" action="/room/{{.roomid}}" method="post"> 
+    User: <input id="user_form" name="user" value="{{.userid}}"></input> 
+    Message: <input id="message_form" name="message"></input> 
+    <input type="submit" value="Submit" /> 
+    </form>
+</body>
+</html>
+`))