1package sockjs 2 3import ( 4 "bufio" 5 "flag" 6 "fmt" 7 "log" 8 "net/http" 9 "net/http/httptest" 10 "net/url" 11 "strings" 12 "sync" 13 "testing" 14 "time" 15 16 "github.com/gorilla/websocket" 17) 18 19func BenchmarkSimple(b *testing.B) { 20 var messages = make(chan string, 10) 21 h := NewHandler("/echo", DefaultOptions, func(session Session) { 22 for m := range messages { 23 _ = session.Send(m) 24 } 25 _ = session.Close(1024, "Close") 26 }) 27 server := httptest.NewServer(h) 28 defer server.Close() 29 30 req, _ := http.NewRequest("POST", server.URL+fmt.Sprintf("/echo/server/%d/xhr_streaming", 1000), nil) 31 resp, err := http.DefaultClient.Do(req) 32 if err != nil { 33 log.Fatal(err) 34 } 35 for n := 0; n < b.N; n++ { 36 messages <- "some message" 37 } 38 fmt.Println(b.N) 39 close(messages) 40 resp.Body.Close() 41} 42 43func BenchmarkMessages(b *testing.B) { 44 msg := strings.Repeat("m", 10) 45 h := NewHandler("/echo", DefaultOptions, func(session Session) { 46 for n := 0; n < b.N; n++ { 47 _ = session.Send(msg) 48 } 49 _ = session.Close(1024, "Close") 50 }) 51 server := httptest.NewServer(h) 52 53 var wg sync.WaitGroup 54 55 for i := 0; i < 100; i++ { 56 wg.Add(1) 57 go func(session int) { 58 reqc := 0 59 req, _ := http.NewRequest("POST", server.URL+fmt.Sprintf("/echo/server/%d/xhr_streaming", session), nil) 60 for { 61 reqc++ 62 resp, err := http.DefaultClient.Do(req) 63 if err != nil { 64 log.Fatal(err) 65 } 66 reader := bufio.NewReader(resp.Body) 67 for { 68 line, err := reader.ReadString('\n') 69 if err != nil { 70 goto AGAIN 71 } 72 if strings.HasPrefix(line, "data: c[1024") { 73 resp.Body.Close() 74 goto DONE 75 } 76 } 77 AGAIN: 78 resp.Body.Close() 79 } 80 DONE: 81 wg.Done() 82 }(i) 83 } 84 wg.Wait() 85 server.Close() 86} 87 88var size = flag.Int("size", 4*1024, "Size of one message.") 89 90func BenchmarkMessageWebsocket(b *testing.B) { 91 flag.Parse() 92 93 msg := strings.Repeat("x", *size) 94 wsFrame := []byte(fmt.Sprintf("[%q]", msg)) 95 96 opts := Options{ 97 Websocket: true, 98 SockJSURL: "//cdnjs.cloudflare.com/ajax/libs/sockjs-client/0.3.4/sockjs.min.js", 99 HeartbeatDelay: time.Hour, 100 DisconnectDelay: time.Hour, 101 ResponseLimit: uint32(*size), 102 } 103 104 h := NewHandler("/echo", opts, func(session Session) { 105 for { 106 msg, err := session.Recv() 107 if err != nil { 108 if session.GetSessionState() != SessionActive { 109 break 110 } 111 b.Fatalf("Recv()=%s", err) 112 } 113 114 if err := session.Send(msg); err != nil { 115 b.Fatalf("Send()=%s", err) 116 } 117 } 118 }) 119 120 server := httptest.NewServer(h) 121 defer server.Close() 122 123 url := "ws" + server.URL[4:] + "/echo/server/0/websocket" 124 125 client, _, err := websocket.DefaultDialer.Dial(url, nil) 126 if err != nil { 127 b.Fatalf("Dial()=%s", err) 128 } 129 130 _, p, err := client.ReadMessage() 131 if err != nil || string(p) != "o" { 132 b.Fatalf("failed to start new session: frame=%v, err=%v", p, err) 133 } 134 135 b.ReportAllocs() 136 b.ResetTimer() 137 138 for i := 0; i < b.N; i++ { 139 if err := client.WriteMessage(websocket.TextMessage, wsFrame); err != nil { 140 b.Fatalf("WriteMessage()=%s", err) 141 } 142 143 if _, _, err := client.ReadMessage(); err != nil { 144 b.Fatalf("ReadMessage()=%s", err) 145 } 146 } 147 148 if err := client.Close(); err != nil { 149 b.Fatalf("Close()=%s", err) 150 } 151} 152 153func BenchmarkHandler_ParseSessionID(b *testing.B) { 154 h := Handler{prefix: "/prefix"} 155 url, _ := url.Parse("http://server:80/prefix/server/session/whatever") 156 157 b.ReportAllocs() 158 b.ResetTimer() 159 for i := 0; i < b.N; i++ { 160 _, _ = h.parseSessionID(url) 161 } 162} 163