websocket 增加多分组 fork https://github.com/olahol/melody
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
5.3 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
5 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
  1. # melody
  2. [![Build Status](https://travis-ci.org/olahol/melody.svg)](https://travis-ci.org/olahol/melody)
  3. [![Coverage Status](https://img.shields.io/coveralls/olahol/melody.svg?style=flat)](https://coveralls.io/r/olahol/melody)
  4. [![GoDoc](https://godoc.org/github.com/olahol/melody?status.svg)](https://godoc.org/github.com/olahol/melody)
  5. > :notes: Minimalist websocket framework for Go.
  6. Melody is websocket framework based on [github.com/gorilla/websocket](https://github.com/gorilla/websocket)
  7. that abstracts away the tedious parts of handling websockets. It gets out of
  8. your way so you can write real-time apps. Features include:
  9. * [x] Clear and easy interface similar to `net/http` or Gin.
  10. * [x] A simple way to broadcast to all or selected connected sessions.
  11. * [x] Message buffers making concurrent writing safe.
  12. * [x] Automatic handling of ping/pong and session timeouts.
  13. * [x] Store data on sessions.
  14. ## Install
  15. ```bash
  16. go get gopkg.in/olahol/melody.v1
  17. ```
  18. ## [Example: sub/pub](https://)
  19. ```go
  20. package main
  21. import (
  22. "log"
  23. "melody"
  24. "github.com/gin-gonic/gin"
  25. )
  26. func main() {
  27. m := melody.New()
  28. router := gin.Default()
  29. router.GET("/chat", func(context *gin.Context) {
  30. if err := m.HandleRequest(context.Writer, context.Request); err != nil {
  31. log.Println(err)
  32. }
  33. })
  34. m.HandleConnect(func(session *melody.Session) {
  35. ch := session.Request.URL.Query().Get("channel")
  36. if err := session.Subscribe(ch); err != nil {
  37. log.Println(err)
  38. }
  39. })
  40. m.HandleMessage(func(session *melody.Session, msg []byte) {
  41. if err := session.Publish(msg); err != nil {
  42. log.Println(err)
  43. }
  44. })
  45. m.HandleSentMessage(func(session *melody.Session, bytes []byte) {
  46. log.Printf("%+v", session.Channel().Online())
  47. log.Printf("%+v", string(bytes))
  48. })
  49. router.Run(":8080")
  50. }
  51. ```
  52. ## [Example: chat](https://github.com/olahol/melody/tree/master/examples/chat)
  53. [![Chat](https://cdn.rawgit.com/olahol/melody/master/examples/chat/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/chat)
  54. Using [Gin](https://github.com/gin-gonic/gin):
  55. ```go
  56. package main
  57. import (
  58. "github.com/gin-gonic/gin"
  59. "gopkg.in/olahol/melody.v1"
  60. "net/http"
  61. )
  62. func main() {
  63. r := gin.Default()
  64. m := melody.New()
  65. r.GET("/", func(c *gin.Context) {
  66. http.ServeFile(c.Writer, c.Request, "index.html")
  67. })
  68. r.GET("/ws", func(c *gin.Context) {
  69. m.HandleRequest(c.Writer, c.Request)
  70. })
  71. m.HandleMessage(func(s *melody.Session, msg []byte) {
  72. m.Broadcast(msg)
  73. })
  74. r.Run(":5000")
  75. }
  76. ```
  77. Using [Echo](https://github.com/labstack/echo):
  78. ```go
  79. package main
  80. import (
  81. "github.com/labstack/echo"
  82. "github.com/labstack/echo/engine/standard"
  83. "github.com/labstack/echo/middleware"
  84. "gopkg.in/olahol/melody.v1"
  85. "net/http"
  86. )
  87. func main() {
  88. e := echo.New()
  89. m := melody.New()
  90. e.Use(middleware.Logger())
  91. e.Use(middleware.Recover())
  92. e.GET("/", func(c echo.Context) error {
  93. http.ServeFile(c.Response().(*standard.Response).ResponseWriter, c.Request().(*standard.Request).Request, "index.html")
  94. return nil
  95. })
  96. e.GET("/ws", func(c echo.Context) error {
  97. m.HandleRequest(c.Response().(*standard.Response).ResponseWriter, c.Request().(*standard.Request).Request)
  98. return nil
  99. })
  100. m.HandleMessage(func(s *melody.Session, msg []byte) {
  101. m.Broadcast(msg)
  102. })
  103. e.Run(standard.New(":5000"))
  104. }
  105. ```
  106. ## [Example: gophers](https://github.com/olahol/melody/tree/master/examples/gophers)
  107. [![Gophers](https://cdn.rawgit.com/olahol/melody/master/examples/gophers/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/gophers)
  108. ```go
  109. package main
  110. import (
  111. "github.com/gin-gonic/gin"
  112. "gopkg.in/olahol/melody.v1"
  113. "net/http"
  114. "strconv"
  115. "strings"
  116. "sync"
  117. )
  118. type GopherInfo struct {
  119. ID, X, Y string
  120. }
  121. func main() {
  122. router := gin.Default()
  123. mrouter := melody.New()
  124. gophers := make(map[*melody.Session]*GopherInfo)
  125. lock := new(sync.Mutex)
  126. counter := 0
  127. router.GET("/", func(c *gin.Context) {
  128. http.ServeFile(c.Writer, c.Request, "index.html")
  129. })
  130. router.GET("/ws", func(c *gin.Context) {
  131. mrouter.HandleRequest(c.Writer, c.Request)
  132. })
  133. mrouter.HandleConnect(func(s *melody.Session) {
  134. lock.Lock()
  135. for _, info := range gophers {
  136. s.Write([]byte("set " + info.ID + " " + info.X + " " + info.Y))
  137. }
  138. gophers[s] = &GopherInfo{strconv.Itoa(counter), "0", "0"}
  139. s.Write([]byte("iam " + gophers[s].ID))
  140. counter += 1
  141. lock.Unlock()
  142. })
  143. mrouter.HandleDisconnect(func(s *melody.Session) {
  144. lock.Lock()
  145. mrouter.BroadcastOthers([]byte("dis "+gophers[s].ID), s)
  146. delete(gophers, s)
  147. lock.Unlock()
  148. })
  149. mrouter.HandleMessage(func(s *melody.Session, msg []byte) {
  150. p := strings.Split(string(msg), " ")
  151. lock.Lock()
  152. info := gophers[s]
  153. if len(p) == 2 {
  154. info.X = p[0]
  155. info.Y = p[1]
  156. mrouter.BroadcastOthers([]byte("set "+info.ID+" "+info.X+" "+info.Y), s)
  157. }
  158. lock.Unlock()
  159. })
  160. router.Run(":5000")
  161. }
  162. ```
  163. ### [More examples](https://github.com/olahol/melody/tree/master/examples)
  164. ## [Documentation](https://godoc.org/github.com/olahol/melody)
  165. ## Contributors
  166. * Ola Holmström (@olahol)
  167. * Shogo Iwano (@shiwano)
  168. * Matt Caldwell (@mattcaldwell)
  169. * Heikki Uljas (@huljas)
  170. * Robbie Trencheny (@robbiet480)
  171. * yangjinecho (@yangjinecho)
  172. ## FAQ
  173. If you are getting a `403` when trying to connect to your websocket you can [change allow all origin hosts](http://godoc.org/github.com/gorilla/websocket#hdr-Origin_Considerations):
  174. ```go
  175. m := melody.New()
  176. m.Upgrader.CheckOrigin = func(r *http.Request) bool { return true }
  177. ```