diff --git a/gcm.go b/gcm.go index 4508f48..ff23b99 100644 --- a/gcm.go +++ b/gcm.go @@ -32,14 +32,15 @@ import ( ) const ( - CCSAck = "ack" - CCSNack = "nack" - CCSControl = "control" - CCSReceipt = "receipt" - httpAddress = "https://gcm-http.googleapis.com/gcm/send" - xmppHost = "gcm.googleapis.com" - xmppPort = "5235" - xmppAddress = xmppHost + ":" + xmppPort + CCSAck = "ack" + CCSNack = "nack" + CCSControl = "control" + CCSReceipt = "receipt" + httpAddress = "https://gcm-http.googleapis.com/gcm/send" + xmppHost = "gcm.googleapis.com" + xmppPort = "5235" + xmppStagingHost = "gcm-staging.googleapis.com" + xmppStagingPort = "5236" // For ccs the min for exponential backoff has to be 1 sec ccsMinBackoff = 1 * time.Second ) @@ -65,6 +66,7 @@ var ( }{ m: make(map[string]*xmppGcmClient), } + xmppAddress = xmppHost + ":" + xmppPort ) // Prints debug info if DebugMode is set. @@ -112,7 +114,7 @@ type HttpResponse struct { Failure uint `json:"failure,omitempty"` CanonicalIds uint `json:"canonical_ids,omitempty"` Results []Result `json:"results,omitempty"` - MessageId int `json:"message_id,omitempty"` + MessageId int `json:"message_id,omitempty"` Error string `json:"error,omitempty"` } @@ -242,13 +244,19 @@ type messageLogEntry struct { // Factory method for xmppGcmClient, to minimize the number of clients to one per sender id. // TODO(silvano): this could be revised, taking into account that we cannot have more than 1000 // connections per senderId. -func newXmppGcmClient(senderID string, apiKey string) (*xmppGcmClient, error) { +func newXmppGcmClient(senderID, apiKey string, isProduction bool) (*xmppGcmClient, error) { xmppClients.Lock() defer xmppClients.Unlock() if xc, ok := xmppClients.m[senderID]; ok { return xc, nil } + if isProduction { + xmppAddress = xmppHost + ":" + xmppPort + } else { + xmppAddress = xmppStagingHost + ":" + xmppStagingPort + } + nc, err := xmpp.NewClient(xmppAddress, xmppUser(senderID), apiKey, DebugMode) if err != nil { return nil, fmt.Errorf("error connecting client>%v", err) @@ -576,7 +584,7 @@ func checkResults(gcmResults []Result, recipients []string, resultsState multica // SendXmpp sends a message using the XMPP GCM connection server. func SendXmpp(senderId, apiKey string, m XmppMessage) (string, int, error) { - c, err := newXmppGcmClient(senderId, apiKey) + c, err := newXmppGcmClient(senderId, apiKey, true) if err != nil { return "", 0, fmt.Errorf("error creating xmpp client>%v", err) } @@ -588,7 +596,28 @@ func SendXmpp(senderId, apiKey string, m XmppMessage) (string, int, error) { // notifications, errors. An optional stop channel can be provided to // stop listening. func Listen(senderId, apiKey string, h MessageHandler, stop <-chan bool) error { - cl, err := newXmppGcmClient(senderId, apiKey) + cl, err := newXmppGcmClient(senderId, apiKey, true) + if err != nil { + return fmt.Errorf("error creating xmpp client>%v", err) + } + return cl.listen(h, stop) +} + +// SendXmppStaging sends a message using the XMPP GCM staging connection server. +func SendXmppStaging(senderId, apiKey string, m XmppMessage) (string, int, error) { + c, err := newXmppGcmClient(senderId, apiKey, false) + if err != nil { + return "", 0, fmt.Errorf("error creating xmpp client>%v", err) + } + return c.send(m) +} + +// ListenStaging blocks and connects to GCM staging waiting for messages, calling the handler +// for CCS message that can be of interest to the listener: upstream messages, delivery receipt +// notifications, errors. An optional stop channel can be provided to +// stop listening. +func ListenStaging(senderId, apiKey string, h MessageHandler, stop <-chan bool) error { + cl, err := newXmppGcmClient(senderId, apiKey, false) if err != nil { return fmt.Errorf("error creating xmpp client>%v", err) }