diff --git a/.pubnub.yml b/.pubnub.yml index cf149072..522fea9e 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,5 +1,15 @@ --- changelog: + - + changes: + - + text: "Fixes for 32bit and armv7 systems" + type: improvement + - + text: "QueryParam and State in Presence Heartbeat" + type: improvement + date: Jan 15, 19 + version: v4.1.6 - changes: - @@ -303,4 +313,4 @@ supported-platforms: - "Mac OS X 10.8 or later, amd64" - "Windows 7 or later, amd64, 386" version: "PubNub Go SDK" -version: v4.1.5 +version: v4.1.6 diff --git a/README.md b/README.md index 89e294c4..77508439 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# PubNub 4.1.5 client for Go +# PubNub 4.1.6 client for Go * Go (1.9+) # Please direct all Support Questions and Concerns to Support@PubNub.com diff --git a/VERSION b/VERSION index b1cbc1fc..561ad334 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.1.5 +4.1.6 diff --git a/examples/cli/cli_demo.go b/examples/cli/cli_demo.go index 39f3f462..e7f69875 100644 --- a/examples/cli/cli_demo.go +++ b/examples/cli/cli_demo.go @@ -360,7 +360,14 @@ func runPresenceRequest(args []string) { if len(args) > 2 { groups = strings.Split(args[2], ",") } - pn.Presence().Connected(connected).Channels(channels).ChannelGroups(groups).Execute() + queryParam := map[string]string{ + "q1": "v1", + "q2": "v2", + } + state := map[string]interface{}{ + "state": "stateval", + } + pn.Presence().Connected(connected).Channels(channels).QueryParam(queryParam).State(state).ChannelGroups(groups).Execute() } func setPresenceTimeout(args []string) { diff --git a/heartbeat_manager.go b/heartbeat_manager.go index eb54a865..29c940d9 100644 --- a/heartbeat_manager.go +++ b/heartbeat_manager.go @@ -20,6 +20,8 @@ type HeartbeatManager struct { ctx Context runIndependentOfSubscribe bool hbRunning bool + queryParam map[string]string + state map[string]interface{} } func newHeartbeatManager(pn *PubNub, context Context) *HeartbeatManager { @@ -156,17 +158,23 @@ func (m *HeartbeatManager) prepareList(subItem map[string]*SubscriptionItem) []s } func (m *HeartbeatManager) performHeartbeatLoop() error { + var stateStorage map[string]interface{} + m.RLock() presenceChannels := m.prepareList(m.heartbeatChannels) presenceGroups := m.prepareList(m.heartbeatGroups) + stateStorage = m.state + queryParam := m.queryParam m.pubnub.Config.Log.Println("performHeartbeatLoop: count presenceChannels, presenceGroups", len(presenceChannels), len(presenceGroups)) m.RUnlock() - var stateStorage map[string]interface{} + if (len(presenceChannels) == 0) && (len(presenceGroups) == 0) { m.pubnub.Config.Log.Println("performHeartbeatLoop: count presenceChannels, presenceGroups nil") presenceChannels = m.pubnub.subscriptionManager.stateManager.prepareChannelList(false) presenceGroups = m.pubnub.subscriptionManager.stateManager.prepareGroupList(false) stateStorage = m.pubnub.subscriptionManager.stateManager.createStatePayload() + queryParam = nil + m.pubnub.Config.Log.Println("performHeartbeatLoop: count sub presenceChannels, presenceGroups", len(presenceChannels), len(presenceGroups)) } @@ -180,6 +188,7 @@ func (m *HeartbeatManager) performHeartbeatLoop() error { Channels(presenceChannels). ChannelGroups(presenceGroups). State(stateStorage). + QueryParam(queryParam). Execute() if err != nil { diff --git a/heartbeat_request.go b/heartbeat_request.go index 33e567f0..c454585d 100644 --- a/heartbeat_request.go +++ b/heartbeat_request.go @@ -39,6 +39,13 @@ func newHeartbeatBuilderWithContext(pubnub *PubNub, return &builder } +// QueryParam accepts a map, the keys and values of the map are passed as the query string parameters of the URL called by the API. +func (b *heartbeatBuilder) QueryParam(queryParam map[string]string) *heartbeatBuilder { + b.opts.QueryParam = queryParam + + return b +} + // State sets the state for the Heartbeat request. func (b *heartbeatBuilder) State(state interface{}) *heartbeatBuilder { b.opts.State = state @@ -84,6 +91,7 @@ type heartbeatOpts struct { Channels []string ChannelGroups []string + QueryParam map[string]string ctx Context } @@ -139,6 +147,7 @@ func (o *heartbeatOpts) buildQuery() (*url.Values, error) { q.Set("state", string(state)) } } + SetQueryParam(q, o.QueryParam) return q, nil } diff --git a/history_request.go b/history_request.go index 6baad636..8756fd59 100644 --- a/history_request.go +++ b/history_request.go @@ -251,7 +251,7 @@ func parseInterface(vv []interface{}, o *historyOpts) []HistoryResponseItem { s := fmt.Sprintf("%.0f", f) o.pubnub.Config.Log.Println("s:", s) - if tt, err := strconv.Atoi(s); err == nil { + if tt, err := strconv.ParseInt(s, 10, 64); err == nil { o.pubnub.Config.Log.Println("tt:", tt) items[i].Timetoken = int64(tt) } else { diff --git a/presence_request.go b/presence_request.go index addc8602..f0a4f409 100644 --- a/presence_request.go +++ b/presence_request.go @@ -15,6 +15,8 @@ type presenceOpts struct { channelGroups []string connected bool ctx Context + queryParam map[string]string + state map[string]interface{} } func newPresenceBuilder(pubnub *PubNub) *presenceBuilder { @@ -59,6 +61,19 @@ func (b *presenceBuilder) Connected(connected bool) *presenceBuilder { return b } +// QueryParam accepts a map, the keys and values of the map are passed as the query string parameters of the URL called by the API. +func (b *presenceBuilder) QueryParam(queryParam map[string]string) *presenceBuilder { + b.opts.queryParam = queryParam + + return b +} + +// State sets the State for the Set State request. +func (b *presenceBuilder) State(state map[string]interface{}) *presenceBuilder { + b.opts.state = state + return b +} + func (b *presenceBuilder) Execute() { if b.opts.connected { for _, ch := range b.opts.channels { @@ -77,12 +92,16 @@ func (b *presenceBuilder) Execute() { b.opts.pubnub.heartbeatManager.heartbeatGroups[cg] = newSubscriptionItem(cg) b.opts.pubnub.heartbeatManager.Unlock() } - + b.opts.pubnub.heartbeatManager.state = b.opts.state + b.opts.pubnub.heartbeatManager.queryParam = b.opts.queryParam b.opts.pubnub.heartbeatManager.startHeartbeatTimer(true) } else { b.opts.pubnub.heartbeatManager.Lock() b.opts.pubnub.heartbeatManager.heartbeatChannels = make(map[string]*SubscriptionItem) b.opts.pubnub.heartbeatManager.heartbeatGroups = make(map[string]*SubscriptionItem) + b.opts.pubnub.heartbeatManager.state = nil + b.opts.pubnub.heartbeatManager.queryParam = nil + b.opts.pubnub.heartbeatManager.Unlock() // b.opts.pubnub.heartbeatManager.stopHeartbeat(true, true) } diff --git a/publish_request.go b/publish_request.go index 875a3f05..c675d71d 100644 --- a/publish_request.go +++ b/publish_request.go @@ -45,7 +45,7 @@ type publishOpts struct { // PublishResponse is the response after the execution on Publish and Fire operations. type PublishResponse struct { - Timestamp int + Timestamp int64 } type publishBuilder struct { @@ -68,7 +68,7 @@ func newPublishResponse(jsonBytes []byte, status StatusResponse) ( if !ok { return emptyPublishResponse, status, pnerr.NewResponseParsingError(fmt.Sprintf("Error unmarshalling response, %s %v", value[2], value), nil, nil) } - timestamp, err := strconv.Atoi(timeString) + timestamp, err := strconv.ParseInt(timeString, 10, 64) if err != nil { return emptyPublishResponse, status, err } diff --git a/pubnub.go b/pubnub.go index be2a25c1..aaa8f78b 100644 --- a/pubnub.go +++ b/pubnub.go @@ -12,7 +12,7 @@ import ( // Default constants const ( // Version :the version of the SDK - Version = "4.1.5" + Version = "4.1.6" // MaxSequence for publish messages MaxSequence = 65535 ) diff --git a/subscription_manager.go b/subscription_manager.go index 45878bbf..61c413a6 100644 --- a/subscription_manager.go +++ b/subscription_manager.go @@ -573,6 +573,9 @@ func processSubscribePayload(m *SubscriptionManager, payload subscribeMessage) { case int: timestamp = int64(presencePayload["timestamp"].(int)) break + case int64: + timestamp = presencePayload["timestamp"].(int64) + break case float64: timestamp = int64(presencePayload["timestamp"].(float64)) break diff --git a/subscription_manager_test.go b/subscription_manager_test.go index 68eddb37..7d576cf8 100644 --- a/subscription_manager_test.go +++ b/subscription_manager_test.go @@ -403,7 +403,7 @@ func TestProcessSubscribePayload(t *testing.T) { payload := &map[string]interface{}{ "action": "join", - "timestamp": 15078947309567840, + "timestamp": int64(15078947309567840), "uuid": "bfce00ff4018fce180438bb04afc8da8", "occupancy": 1, } @@ -504,7 +504,7 @@ func TestProcessSubscribePayloadSubMatch(t *testing.T) { payload := &map[string]interface{}{ "action": "join", - "timestamp": 15078947309567840, + "timestamp": int64(15078947309567840), "uuid": "bfce00ff4018fce180438bb04afc8da8", "occupancy": 1, "here_now_refresh": true,