diff --git a/examples/realtime-chat/main.go b/examples/realtime-chat/main.go new file mode 100644 index 00000000..4eb5e502 --- /dev/null +++ b/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) +} diff --git a/examples/realtime-chat/rooms.go b/examples/realtime-chat/rooms.go new file mode 100644 index 00000000..8c62bece --- /dev/null +++ b/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 +} diff --git a/examples/realtime-chat/template.go b/examples/realtime-chat/template.go new file mode 100644 index 00000000..b9024de6 --- /dev/null +++ b/examples/realtime-chat/template.go @@ -0,0 +1,44 @@ +package main + +import "html/template" + +var html = template.Must(template.New("chat_room").Parse(` + +
+