@@ -78,9 +78,9 @@ const (
78
78
79
79
var (
80
80
topicRegex = regexp .MustCompile (`^/[-_A-Za-z0-9]{1,64}$` ) // Regex must match JS & Android app!
81
- jsonRegex = regexp .MustCompile (`^/[-_A-Za-z0-9]{1,64}/json$` )
82
- sseRegex = regexp .MustCompile (`^/[-_A-Za-z0-9]{1,64}/sse$` )
83
- rawRegex = regexp .MustCompile (`^/[-_A-Za-z0-9]{1,64}/raw$` )
81
+ jsonRegex = regexp .MustCompile (`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})* /json$` )
82
+ sseRegex = regexp .MustCompile (`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})* /sse$` )
83
+ rawRegex = regexp .MustCompile (`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})* /raw$` )
84
84
85
85
staticRegex = regexp .MustCompile (`^/static/.+` )
86
86
@@ -223,7 +223,7 @@ func (s *Server) handleStatic(w http.ResponseWriter, r *http.Request) error {
223
223
}
224
224
225
225
func (s * Server ) handlePublish (w http.ResponseWriter , r * http.Request , v * visitor ) error {
226
- t , err := s .topic (r .URL .Path [1 :])
226
+ t , err := s .topicFromID (r .URL .Path [1 :])
227
227
if err != nil {
228
228
return err
229
229
}
@@ -289,7 +289,9 @@ func (s *Server) handleSubscribe(w http.ResponseWriter, r *http.Request, v *visi
289
289
return errHTTPTooManyRequests
290
290
}
291
291
defer v .RemoveSubscription ()
292
- t , err := s .topic (strings .TrimSuffix (r .URL .Path [1 :], "/" + format )) // Hack
292
+ topicsStr := strings .TrimSuffix (r .URL .Path [1 :], "/" + format ) // Hack
293
+ topicIDs := strings .Split (topicsStr , "," )
294
+ topics , err := s .topicsFromIDs (topicIDs ... )
293
295
if err != nil {
294
296
return err
295
297
}
@@ -314,14 +316,21 @@ func (s *Server) handleSubscribe(w http.ResponseWriter, r *http.Request, v *visi
314
316
w .Header ().Set ("Access-Control-Allow-Origin" , "*" ) // CORS, allow cross-origin requests
315
317
w .Header ().Set ("Content-Type" , contentType + "; charset=utf-8" ) // Android/Volley client needs charset!
316
318
if poll {
317
- return s .sendOldMessages (t , since , sub )
319
+ return s .sendOldMessages (topics , since , sub )
318
320
}
319
- subscriberID := t .Subscribe (sub )
320
- defer t .Unsubscribe (subscriberID )
321
- if err := sub (newOpenMessage (t .id )); err != nil { // Send out open message
321
+ subscriberIDs := make ([]int , 0 )
322
+ for _ , t := range topics {
323
+ subscriberIDs = append (subscriberIDs , t .Subscribe (sub ))
324
+ }
325
+ defer func () {
326
+ for i , subscriberID := range subscriberIDs {
327
+ topics [i ].Unsubscribe (subscriberID ) // Order!
328
+ }
329
+ }()
330
+ if err := sub (newOpenMessage (topicsStr )); err != nil { // Send out open message
322
331
return err
323
332
}
324
- if err := s .sendOldMessages (t , since , sub ); err != nil {
333
+ if err := s .sendOldMessages (topics , since , sub ); err != nil {
325
334
return err
326
335
}
327
336
for {
@@ -330,25 +339,27 @@ func (s *Server) handleSubscribe(w http.ResponseWriter, r *http.Request, v *visi
330
339
return nil
331
340
case <- time .After (s .config .KeepaliveInterval ):
332
341
v .Keepalive ()
333
- if err := sub (newKeepaliveMessage (t . id )); err != nil { // Send keepalive message
342
+ if err := sub (newKeepaliveMessage (topicsStr )); err != nil { // Send keepalive message
334
343
return err
335
344
}
336
345
}
337
346
}
338
347
}
339
348
340
- func (s * Server ) sendOldMessages (t * topic , since sinceTime , sub subscriber ) error {
349
+ func (s * Server ) sendOldMessages (topics [] * topic , since sinceTime , sub subscriber ) error {
341
350
if since .IsNone () {
342
351
return nil
343
352
}
344
- messages , err := s .cache .Messages (t .id , since )
345
- if err != nil {
346
- return err
347
- }
348
- for _ , m := range messages {
349
- if err := sub (m ); err != nil {
353
+ for _ , t := range topics {
354
+ messages , err := s .cache .Messages (t .id , since )
355
+ if err != nil {
350
356
return err
351
357
}
358
+ for _ , m := range messages {
359
+ if err := sub (m ); err != nil {
360
+ return err
361
+ }
362
+ }
352
363
}
353
364
return nil
354
365
}
@@ -382,19 +393,31 @@ func (s *Server) handleOptions(w http.ResponseWriter, r *http.Request) error {
382
393
return nil
383
394
}
384
395
385
- func (s * Server ) topic (id string ) (* topic , error ) {
396
+ func (s * Server ) topicFromID (id string ) (* topic , error ) {
397
+ topics , err := s .topicsFromIDs (id )
398
+ if err != nil {
399
+ return nil , err
400
+ }
401
+ return topics [0 ], nil
402
+ }
403
+
404
+ func (s * Server ) topicsFromIDs (ids ... string ) ([]* topic , error ) {
386
405
s .mu .Lock ()
387
406
defer s .mu .Unlock ()
388
- if _ , ok := s .topics [id ]; ! ok {
389
- if len (s .topics ) >= s .config .GlobalTopicLimit {
390
- return nil , errHTTPTooManyRequests
391
- }
392
- s .topics [id ] = newTopic (id , time .Now ())
393
- if s .firebase != nil {
394
- s .topics [id ].Subscribe (s .firebase )
407
+ topics := make ([]* topic , 0 )
408
+ for _ , id := range ids {
409
+ if _ , ok := s .topics [id ]; ! ok {
410
+ if len (s .topics ) >= s .config .GlobalTopicLimit {
411
+ return nil , errHTTPTooManyRequests
412
+ }
413
+ s .topics [id ] = newTopic (id , time .Now ())
414
+ if s .firebase != nil {
415
+ s .topics [id ].Subscribe (s .firebase )
416
+ }
395
417
}
418
+ topics = append (topics , s .topics [id ])
396
419
}
397
- return s . topics [ id ] , nil
420
+ return topics , nil
398
421
}
399
422
400
423
func (s * Server ) updateStatsAndExpire () {
0 commit comments