# # Common utility functions to help deal with subscriptions to the server # $ = jQuery context = window context.JK ||= {}; class SubscriptionUtils constructor: () -> @logger = context.JK.logger @msgFactory = context.JK.MessageFactory; @subscriptions = {} @events = context.JK.EVENTS; @reconnectRegistrationTimeout = null this.init() init: () => # once JamKazam is fully loaded, watch for SUBSCRIPTION_MESSAGE events $(document).on('JAMKAZAM_READY', this.registerWithGateway) genKey:(type, id) => type + ":" + id test: () => this.subscribe('test', '1') this.subscribe('test', '2') reregister: () => # re-register all existing watches @reconnectRegistrationTimeout = null if context.JK.dlen(@subscriptions) > 0 bulkSubscribe = [] types = [] ids = [] for key, watch of @subscriptions bits = key.split(':') type = bits[0] id = bits[1] types.push(type) ids.push(id) # bulkSubscribe.push({type: type, id:id}) # send a special message which contains all subscriptions in one message msg = @msgFactory.subscribeBulk(types, ids) context.JK.JamServer.send(msg) # whenever we reconnect, set a timer to automatically re-subscribe to any outstanding subscriptions onConnectionUp: () => #this.test() if @reconnectRegistrationTimeout? clearTimeout(@reconnectRegistrationTimeout) if context.JK.dlen(@subscriptions) > 0 @reconnectRegistrationTimeout = setTimeout(this.reregister, 1000) # re-register after 1 second, to prevent excessive messaging to server onConnectionDown: () => if @reconnectRegistrationTimeout? clearTimeout(@reconnectRegistrationTimeout) registerWithGateway: () => context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SUBSCRIPTION_MESSAGE, this.onSubscriptionMessage); $server = context.JK.JamServer.get$Server() $server.on(@events.CONNECTION_UP, this.onConnectionUp) $server.on(@events.CONNECTION_DOWN, this.onConnectionDown) onSubscriptionMessage: (header, payload) => console.log("onSubscriptionMessage", payload, header) key = this.genKey(payload.type, payload.id) watch = @subscriptions[key] if watch watch.triggerHandler(@events.SUBSCRIBE_NOTIFICATION, {type:payload.type, id: payload.id, body: JSON.parse(payload.body)}) else @logger.warn("unable to find subscription for #{key}") # call subscribe, and use the returned object to listen for events of name context.JK.EVENTS.SUBSCRIBE_NOTIFICATION subscribe: (type, id) => id = id.toString() key = this.genKey(type, id) @logger.debug("subscribing for any notifications for #{key}") watch = @subscriptions[key] unless watch? watch = $({type: type, id: id}) @subscriptions[key] = watch # tell server we want messages for this entity msg = @msgFactory.subscribe(type, id) context.JK.JamServer.send(msg) # watch can be used to watch for events using jquery watch # TODO: this should not send a unsubscribe message to the server it's the last listener for the specific type/id combo unsubscribe: (type, id) => id = id.toString() key = this.genKey(type, id) @logger.debug("unsubscribing for any notifications for #{key}") watch = @subscriptions[key] delete @subscriptions[key] # tell server we don't want any more messages for this entity msg = @msgFactory.unsubscribe(type, id) context.JK.JamServer.send(msg) if watch # unattach any events watch.off(); watch # global instance context.JK.SubscriptionUtils = new SubscriptionUtils()