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.

544 lines
10 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
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
  1. package melody
  2. import (
  3. "bytes"
  4. "github.com/gorilla/websocket"
  5. "net/http"
  6. "net/http/httptest"
  7. "strings"
  8. "testing"
  9. "testing/quick"
  10. "time"
  11. )
  12. type TestServer struct {
  13. m *Melody
  14. }
  15. func NewTestServerHandler(handler handleMessageFunc) *TestServer {
  16. m := New()
  17. m.HandleMessage(handler)
  18. return &TestServer{
  19. m: m,
  20. }
  21. }
  22. func NewTestServer() *TestServer {
  23. m := New()
  24. return &TestServer{
  25. m: m,
  26. }
  27. }
  28. func (s *TestServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  29. s.m.HandleRequest(w, r)
  30. }
  31. func NewDialer(url string) (*websocket.Conn, error) {
  32. dialer := &websocket.Dialer{}
  33. conn, _, err := dialer.Dial(strings.Replace(url, "http", "ws", 1), nil)
  34. return conn, err
  35. }
  36. func TestEcho(t *testing.T) {
  37. echo := NewTestServerHandler(func(session *Session, msg []byte) {
  38. session.Write(msg)
  39. })
  40. server := httptest.NewServer(echo)
  41. defer server.Close()
  42. fn := func(msg string) bool {
  43. conn, err := NewDialer(server.URL)
  44. defer conn.Close()
  45. if err != nil {
  46. t.Error(err)
  47. return false
  48. }
  49. conn.WriteMessage(websocket.TextMessage, []byte(msg))
  50. _, ret, err := conn.ReadMessage()
  51. if err != nil {
  52. t.Error(err)
  53. return false
  54. }
  55. if msg != string(ret) {
  56. t.Errorf("%s should equal %s", msg, string(ret))
  57. return false
  58. }
  59. return true
  60. }
  61. if err := quick.Check(fn, nil); err != nil {
  62. t.Error(err)
  63. }
  64. }
  65. func TestEchoBinary(t *testing.T) {
  66. echo := NewTestServer()
  67. echo.m.HandleMessageBinary(func(session *Session, msg []byte) {
  68. session.WriteBinary(msg)
  69. })
  70. server := httptest.NewServer(echo)
  71. defer server.Close()
  72. fn := func(msg string) bool {
  73. conn, err := NewDialer(server.URL)
  74. defer conn.Close()
  75. if err != nil {
  76. t.Error(err)
  77. return false
  78. }
  79. conn.WriteMessage(websocket.BinaryMessage, []byte(msg))
  80. _, ret, err := conn.ReadMessage()
  81. if err != nil {
  82. t.Error(err)
  83. return false
  84. }
  85. if msg != string(ret) {
  86. t.Errorf("%s should equal %s", msg, string(ret))
  87. return false
  88. }
  89. return true
  90. }
  91. if err := quick.Check(fn, nil); err != nil {
  92. t.Error(err)
  93. }
  94. }
  95. func TestHandlers(t *testing.T) {
  96. echo := NewTestServer()
  97. echo.m.HandleMessage(func(session *Session, msg []byte) {
  98. session.Write(msg)
  99. })
  100. server := httptest.NewServer(echo)
  101. defer server.Close()
  102. var q *Session
  103. echo.m.HandleConnect(func(session *Session) {
  104. q = session
  105. session.Close()
  106. })
  107. echo.m.HandleDisconnect(func(session *Session) {
  108. if q != session {
  109. t.Error("disconnecting session should be the same as connecting")
  110. }
  111. })
  112. NewDialer(server.URL)
  113. }
  114. func TestUpgrader(t *testing.T) {
  115. broadcast := NewTestServer()
  116. broadcast.m.HandleMessage(func(session *Session, msg []byte) {
  117. session.Write(msg)
  118. })
  119. server := httptest.NewServer(broadcast)
  120. defer server.Close()
  121. broadcast.m.Upgrader = &websocket.Upgrader{
  122. ReadBufferSize: 1024,
  123. WriteBufferSize: 1024,
  124. CheckOrigin: func(r *http.Request) bool { return false },
  125. }
  126. broadcast.m.HandleError(func(session *Session, err error) {
  127. if err == nil || err.Error() != "websocket: origin not allowed" {
  128. t.Error("there should be a origin error")
  129. }
  130. })
  131. _, err := NewDialer(server.URL)
  132. if err == nil || err.Error() != "websocket: bad handshake" {
  133. t.Error("there should be a badhandshake error")
  134. }
  135. }
  136. func TestBroadcast(t *testing.T) {
  137. broadcast := NewTestServer()
  138. broadcast.m.HandleMessage(func(session *Session, msg []byte) {
  139. broadcast.m.Broadcast(msg)
  140. })
  141. server := httptest.NewServer(broadcast)
  142. defer server.Close()
  143. n := 10
  144. fn := func(msg string) bool {
  145. conn, _ := NewDialer(server.URL)
  146. defer conn.Close()
  147. listeners := make([]*websocket.Conn, n)
  148. for i := 0; i < n; i++ {
  149. listener, _ := NewDialer(server.URL)
  150. listeners[i] = listener
  151. defer listeners[i].Close()
  152. }
  153. conn.WriteMessage(websocket.TextMessage, []byte(msg))
  154. for i := 0; i < n; i++ {
  155. _, ret, err := listeners[i].ReadMessage()
  156. if err != nil {
  157. t.Error(err)
  158. return false
  159. }
  160. if msg != string(ret) {
  161. t.Errorf("%s should equal %s", msg, string(ret))
  162. return false
  163. }
  164. }
  165. return true
  166. }
  167. if !fn("test") {
  168. t.Errorf("should not be false")
  169. }
  170. }
  171. func TestBroadcastBinary(t *testing.T) {
  172. broadcast := NewTestServer()
  173. broadcast.m.HandleMessageBinary(func(session *Session, msg []byte) {
  174. broadcast.m.BroadcastBinary(msg)
  175. })
  176. server := httptest.NewServer(broadcast)
  177. defer server.Close()
  178. n := 10
  179. fn := func(msg []byte) bool {
  180. conn, _ := NewDialer(server.URL)
  181. defer conn.Close()
  182. listeners := make([]*websocket.Conn, n)
  183. for i := 0; i < n; i++ {
  184. listener, _ := NewDialer(server.URL)
  185. listeners[i] = listener
  186. defer listeners[i].Close()
  187. }
  188. conn.WriteMessage(websocket.BinaryMessage, []byte(msg))
  189. for i := 0; i < n; i++ {
  190. messageType, ret, err := listeners[i].ReadMessage()
  191. if err != nil {
  192. t.Error(err)
  193. return false
  194. }
  195. if messageType != websocket.BinaryMessage {
  196. t.Errorf("message type should be BinaryMessage")
  197. return false
  198. }
  199. if !bytes.Equal(msg, ret) {
  200. t.Errorf("%v should equal %v", msg, ret)
  201. return false
  202. }
  203. }
  204. return true
  205. }
  206. if !fn([]byte{2, 3, 5, 7, 11}) {
  207. t.Errorf("should not be false")
  208. }
  209. }
  210. func TestBroadcastOthers(t *testing.T) {
  211. broadcast := NewTestServer()
  212. broadcast.m.HandleMessage(func(session *Session, msg []byte) {
  213. broadcast.m.BroadcastOthers(msg, session)
  214. })
  215. broadcast.m.Config.PongWait = time.Second
  216. broadcast.m.Config.PingPeriod = time.Second * 9 / 10
  217. server := httptest.NewServer(broadcast)
  218. defer server.Close()
  219. n := 10
  220. fn := func(msg string) bool {
  221. conn, _ := NewDialer(server.URL)
  222. defer conn.Close()
  223. listeners := make([]*websocket.Conn, n)
  224. for i := 0; i < n; i++ {
  225. listener, _ := NewDialer(server.URL)
  226. listeners[i] = listener
  227. defer listeners[i].Close()
  228. }
  229. conn.WriteMessage(websocket.TextMessage, []byte(msg))
  230. for i := 0; i < n; i++ {
  231. _, ret, err := listeners[i].ReadMessage()
  232. if err != nil {
  233. t.Error(err)
  234. return false
  235. }
  236. if msg != string(ret) {
  237. t.Errorf("%s should equal %s", msg, string(ret))
  238. return false
  239. }
  240. }
  241. return true
  242. }
  243. if !fn("test") {
  244. t.Errorf("should not be false")
  245. }
  246. }
  247. func TestBroadcastBinaryOthers(t *testing.T) {
  248. broadcast := NewTestServer()
  249. broadcast.m.HandleMessageBinary(func(session *Session, msg []byte) {
  250. broadcast.m.BroadcastBinaryOthers(msg, session)
  251. })
  252. broadcast.m.Config.PongWait = time.Second
  253. broadcast.m.Config.PingPeriod = time.Second * 9 / 10
  254. server := httptest.NewServer(broadcast)
  255. defer server.Close()
  256. n := 10
  257. fn := func(msg []byte) bool {
  258. conn, _ := NewDialer(server.URL)
  259. defer conn.Close()
  260. listeners := make([]*websocket.Conn, n)
  261. for i := 0; i < n; i++ {
  262. listener, _ := NewDialer(server.URL)
  263. listeners[i] = listener
  264. defer listeners[i].Close()
  265. }
  266. conn.WriteMessage(websocket.BinaryMessage, []byte(msg))
  267. for i := 0; i < n; i++ {
  268. messageType, ret, err := listeners[i].ReadMessage()
  269. if err != nil {
  270. t.Error(err)
  271. return false
  272. }
  273. if messageType != websocket.BinaryMessage {
  274. t.Errorf("message type should be BinaryMessage")
  275. return false
  276. }
  277. if !bytes.Equal(msg, ret) {
  278. t.Errorf("%v should equal %v", msg, ret)
  279. return false
  280. }
  281. }
  282. return true
  283. }
  284. if !fn([]byte{2, 3, 5, 7, 11}) {
  285. t.Errorf("should not be false")
  286. }
  287. }
  288. func TestPingPong(t *testing.T) {
  289. noecho := NewTestServer()
  290. noecho.m.Config.PongWait = time.Second
  291. noecho.m.Config.PingPeriod = time.Second * 9 / 10
  292. server := httptest.NewServer(noecho)
  293. defer server.Close()
  294. conn, err := NewDialer(server.URL)
  295. conn.SetPingHandler(func(string) error {
  296. return nil
  297. })
  298. defer conn.Close()
  299. if err != nil {
  300. t.Error(err)
  301. }
  302. conn.WriteMessage(websocket.TextMessage, []byte("test"))
  303. _, _, err = conn.ReadMessage()
  304. if err == nil {
  305. t.Error("there should be an error")
  306. }
  307. }
  308. func TestBroadcastFilter(t *testing.T) {
  309. broadcast := NewTestServer()
  310. broadcast.m.HandleMessage(func(session *Session, msg []byte) {
  311. broadcast.m.BroadcastFilter(msg, func(q *Session) bool {
  312. return session == q
  313. })
  314. })
  315. server := httptest.NewServer(broadcast)
  316. defer server.Close()
  317. fn := func(msg string) bool {
  318. conn, err := NewDialer(server.URL)
  319. defer conn.Close()
  320. if err != nil {
  321. t.Error(err)
  322. return false
  323. }
  324. conn.WriteMessage(websocket.TextMessage, []byte(msg))
  325. _, ret, err := conn.ReadMessage()
  326. if err != nil {
  327. t.Error(err)
  328. return false
  329. }
  330. if msg != string(ret) {
  331. t.Errorf("%s should equal %s", msg, string(ret))
  332. return false
  333. }
  334. return true
  335. }
  336. if !fn("test") {
  337. t.Errorf("should not be false")
  338. }
  339. }
  340. func TestBroadcastBinaryFilter(t *testing.T) {
  341. broadcast := NewTestServer()
  342. broadcast.m.HandleMessageBinary(func(session *Session, msg []byte) {
  343. broadcast.m.BroadcastBinaryFilter(msg, func(q *Session) bool {
  344. return session == q
  345. })
  346. })
  347. server := httptest.NewServer(broadcast)
  348. defer server.Close()
  349. fn := func(msg []byte) bool {
  350. conn, err := NewDialer(server.URL)
  351. defer conn.Close()
  352. if err != nil {
  353. t.Error(err)
  354. return false
  355. }
  356. conn.WriteMessage(websocket.BinaryMessage, []byte(msg))
  357. messageType, ret, err := conn.ReadMessage()
  358. if err != nil {
  359. t.Error(err)
  360. return false
  361. }
  362. if messageType != websocket.BinaryMessage {
  363. t.Errorf("message type should be BinaryMessage")
  364. return false
  365. }
  366. if !bytes.Equal(msg, ret) {
  367. t.Errorf("%v should equal %v", msg, ret)
  368. return false
  369. }
  370. return true
  371. }
  372. if !fn([]byte{2, 3, 5, 7, 11}) {
  373. t.Errorf("should not be false")
  374. }
  375. }
  376. func TestStop(t *testing.T) {
  377. noecho := NewTestServer()
  378. server := httptest.NewServer(noecho)
  379. defer server.Close()
  380. conn, err := NewDialer(server.URL)
  381. defer conn.Close()
  382. if err != nil {
  383. t.Error(err)
  384. }
  385. noecho.m.Close()
  386. }
  387. func TestSmallMessageBuffer(t *testing.T) {
  388. echo := NewTestServerHandler(func(session *Session, msg []byte) {
  389. session.Write(msg)
  390. })
  391. echo.m.Config.MessageBufferSize = 0
  392. echo.m.HandleError(func(s *Session, err error) {
  393. if err == nil {
  394. t.Error("there should be a buffer full error here")
  395. }
  396. })
  397. server := httptest.NewServer(echo)
  398. defer server.Close()
  399. conn, err := NewDialer(server.URL)
  400. defer conn.Close()
  401. if err != nil {
  402. t.Error(err)
  403. }
  404. conn.WriteMessage(websocket.TextMessage, []byte("12345"))
  405. }
  406. func TestPong(t *testing.T) {
  407. echo := NewTestServerHandler(func(session *Session, msg []byte) {
  408. session.Write(msg)
  409. })
  410. echo.m.Config.PongWait = time.Second
  411. echo.m.Config.PingPeriod = time.Second * 9 / 10
  412. server := httptest.NewServer(echo)
  413. defer server.Close()
  414. conn, err := NewDialer(server.URL)
  415. defer conn.Close()
  416. if err != nil {
  417. t.Error(err)
  418. }
  419. fired := false
  420. echo.m.HandlePong(func(s *Session) {
  421. fired = true
  422. })
  423. conn.WriteMessage(websocket.PongMessage, nil)
  424. time.Sleep(time.Millisecond)
  425. if !fired {
  426. t.Error("should have fired pong handler")
  427. }
  428. }