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.

339 lines
6.4 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
10 years ago
  1. package melody
  2. import (
  3. "github.com/gorilla/websocket"
  4. "net/http"
  5. "net/http/httptest"
  6. "strings"
  7. "testing"
  8. "testing/quick"
  9. "time"
  10. )
  11. type TestServer struct {
  12. m *Melody
  13. }
  14. func NewTestServerHandler(handler handleMessageFunc) *TestServer {
  15. m := New()
  16. m.HandleMessage(handler)
  17. return &TestServer{
  18. m: m,
  19. }
  20. }
  21. func NewTestServer() *TestServer {
  22. m := New()
  23. return &TestServer{
  24. m: m,
  25. }
  26. }
  27. func (s *TestServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  28. s.m.HandleRequest(w, r)
  29. }
  30. func NewDialer(url string) (*websocket.Conn, error) {
  31. dialer := &websocket.Dialer{}
  32. conn, _, err := dialer.Dial(strings.Replace(url, "http", "ws", 1), nil)
  33. return conn, err
  34. }
  35. func TestEcho(t *testing.T) {
  36. echo := NewTestServerHandler(func(session *Session, msg []byte) {
  37. session.Write(msg)
  38. })
  39. server := httptest.NewServer(echo)
  40. defer server.Close()
  41. fn := func(msg string) bool {
  42. conn, err := NewDialer(server.URL)
  43. defer conn.Close()
  44. if err != nil {
  45. t.Error(err)
  46. return false
  47. }
  48. conn.WriteMessage(websocket.TextMessage, []byte(msg))
  49. _, ret, err := conn.ReadMessage()
  50. if err != nil {
  51. t.Error(err)
  52. return false
  53. }
  54. if msg != string(ret) {
  55. t.Errorf("%s should equal %s", msg, string(ret))
  56. return false
  57. }
  58. return true
  59. }
  60. if err := quick.Check(fn, nil); err != nil {
  61. t.Error(err)
  62. }
  63. }
  64. func TestEchoBinary(t *testing.T) {
  65. echo := NewTestServer()
  66. echo.m.HandleMessageBinary(func(session *Session, msg []byte) {
  67. session.WriteBinary(msg)
  68. })
  69. server := httptest.NewServer(echo)
  70. defer server.Close()
  71. fn := func(msg string) bool {
  72. conn, err := NewDialer(server.URL)
  73. defer conn.Close()
  74. if err != nil {
  75. t.Error(err)
  76. return false
  77. }
  78. conn.WriteMessage(websocket.BinaryMessage, []byte(msg))
  79. _, ret, err := conn.ReadMessage()
  80. if err != nil {
  81. t.Error(err)
  82. return false
  83. }
  84. if msg != string(ret) {
  85. t.Errorf("%s should equal %s", msg, string(ret))
  86. return false
  87. }
  88. return true
  89. }
  90. if err := quick.Check(fn, nil); err != nil {
  91. t.Error(err)
  92. }
  93. }
  94. func TestHandlers(t *testing.T) {
  95. echo := NewTestServer()
  96. echo.m.HandleMessage(func(session *Session, msg []byte) {
  97. session.Write(msg)
  98. })
  99. server := httptest.NewServer(echo)
  100. defer server.Close()
  101. var q *Session
  102. echo.m.HandleConnect(func(session *Session) {
  103. q = session
  104. session.Close()
  105. })
  106. echo.m.HandleDisconnect(func(session *Session) {
  107. if q != session {
  108. t.Error("disconnecting session should be the same as connecting")
  109. }
  110. })
  111. NewDialer(server.URL)
  112. }
  113. func TestUpgrader(t *testing.T) {
  114. broadcast := NewTestServer()
  115. broadcast.m.HandleMessage(func(session *Session, msg []byte) {
  116. session.Write(msg)
  117. })
  118. server := httptest.NewServer(broadcast)
  119. defer server.Close()
  120. broadcast.m.Upgrader = &websocket.Upgrader{
  121. ReadBufferSize: 1024,
  122. WriteBufferSize: 1024,
  123. CheckOrigin: func(r *http.Request) bool { return false },
  124. }
  125. broadcast.m.HandleError(func(session *Session, err error) {
  126. if err == nil || err.Error() != "websocket: origin not allowed" {
  127. t.Error("there should be a origin error")
  128. }
  129. })
  130. _, err := NewDialer(server.URL)
  131. if err == nil || err.Error() != "websocket: bad handshake" {
  132. t.Error("there should be a badhandshake error")
  133. }
  134. }
  135. func TestBroadcast(t *testing.T) {
  136. broadcast := NewTestServer()
  137. broadcast.m.HandleMessage(func(session *Session, msg []byte) {
  138. broadcast.m.Broadcast(msg)
  139. })
  140. server := httptest.NewServer(broadcast)
  141. defer server.Close()
  142. n := 10
  143. fn := func(msg string) bool {
  144. conn, _ := NewDialer(server.URL)
  145. defer conn.Close()
  146. listeners := make([]*websocket.Conn, n)
  147. for i := 0; i < n; i++ {
  148. listener, _ := NewDialer(server.URL)
  149. listeners[i] = listener
  150. defer listeners[i].Close()
  151. }
  152. conn.WriteMessage(websocket.TextMessage, []byte(msg))
  153. for i := 0; i < n; i++ {
  154. _, ret, err := listeners[i].ReadMessage()
  155. if err != nil {
  156. t.Error(err)
  157. return false
  158. }
  159. if msg != string(ret) {
  160. t.Errorf("%s should equal %s", msg, string(ret))
  161. return false
  162. }
  163. }
  164. _, ret, err := conn.ReadMessage()
  165. if err != nil {
  166. t.Error(err)
  167. return false
  168. }
  169. if msg != string(ret) {
  170. t.Errorf("%s should equal %s", msg, string(ret))
  171. return false
  172. }
  173. return true
  174. }
  175. if err := quick.Check(fn, nil); err != nil {
  176. t.Error(err)
  177. }
  178. }
  179. func TestBroadcastOthers(t *testing.T) {
  180. broadcast := NewTestServer()
  181. broadcast.m.HandleMessage(func(session *Session, msg []byte) {
  182. broadcast.m.BroadcastOthers(msg, session)
  183. })
  184. broadcast.m.Config.PongWait = time.Second
  185. broadcast.m.Config.PingPeriod = time.Second * 9 / 10
  186. server := httptest.NewServer(broadcast)
  187. defer server.Close()
  188. n := 10
  189. fn := func(msg string) bool {
  190. conn, _ := NewDialer(server.URL)
  191. defer conn.Close()
  192. listeners := make([]*websocket.Conn, n)
  193. for i := 0; i < n; i++ {
  194. listener, _ := NewDialer(server.URL)
  195. listeners[i] = listener
  196. defer listeners[i].Close()
  197. }
  198. conn.WriteMessage(websocket.TextMessage, []byte(msg))
  199. for i := 0; i < n; i++ {
  200. _, ret, err := listeners[i].ReadMessage()
  201. if err != nil {
  202. t.Error(err)
  203. return false
  204. }
  205. if msg != string(ret) {
  206. t.Errorf("%s should equal %s", msg, string(ret))
  207. return false
  208. }
  209. }
  210. return true
  211. }
  212. if err := quick.Check(fn, nil); err != nil {
  213. t.Error(err)
  214. }
  215. }
  216. func TestPingPong(t *testing.T) {
  217. noecho := NewTestServer()
  218. noecho.m.Config.PongWait = time.Second
  219. noecho.m.Config.PingPeriod = time.Second * 9 / 10
  220. server := httptest.NewServer(noecho)
  221. defer server.Close()
  222. conn, err := NewDialer(server.URL)
  223. conn.SetPingHandler(func(string) error {
  224. return nil
  225. })
  226. defer conn.Close()
  227. if err != nil {
  228. t.Error(err)
  229. }
  230. conn.WriteMessage(websocket.TextMessage, []byte("test"))
  231. _, _, err = conn.ReadMessage()
  232. if err == nil {
  233. t.Error("there should be an error")
  234. }
  235. }
  236. func TestBroadcastFilter(t *testing.T) {
  237. broadcast := NewTestServer()
  238. broadcast.m.HandleMessage(func(session *Session, msg []byte) {
  239. broadcast.m.BroadcastFilter(msg, func(q *Session) bool {
  240. return session == q
  241. })
  242. })
  243. server := httptest.NewServer(broadcast)
  244. defer server.Close()
  245. fn := func(msg string) bool {
  246. conn, err := NewDialer(server.URL)
  247. defer conn.Close()
  248. if err != nil {
  249. t.Error(err)
  250. return false
  251. }
  252. conn.WriteMessage(websocket.TextMessage, []byte(msg))
  253. _, ret, err := conn.ReadMessage()
  254. if err != nil {
  255. t.Error(err)
  256. return false
  257. }
  258. if msg != string(ret) {
  259. t.Errorf("%s should equal %s", msg, string(ret))
  260. return false
  261. }
  262. return true
  263. }
  264. if err := quick.Check(fn, nil); err != nil {
  265. t.Error(err)
  266. }
  267. }