centrifuge 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba5c864abe1565955d39b965a5c3dda37b897e38
4
- data.tar.gz: a2556ffb9bd65baf236db356f838962e35f31f75
3
+ metadata.gz: 09218a5c452092b2bd0c00132c2031d8fd21af6b
4
+ data.tar.gz: bb4e9c00f0859455b30bbb1dd21e163e6f8bdaed
5
5
  SHA512:
6
- metadata.gz: acf8828ddbabe12564dfec71dcaaf1e60dbff9cc938c62c251c1f61b051383df6f3cc50439d0d71c29aef9c16332eaee137d72ce9d190da6a41c2fa8cfe7ee3c
7
- data.tar.gz: 4b148fb0bdc648fd4a6d3b416ffff6b97c1722effed87e4330b5871ca91462f618cbaad023047ae633c1ce44539435f5e034e0062090f8093c053e016403e81e
6
+ metadata.gz: 0f3d5e00f2b98b8449adc2d0ba3cb68ee3fa75ea2f2756c1356f53d7101310cd4b53f9792301a308b130e5d8de8abb8ac8a4c4ded3c4c0aabf9dbd34e29c6056
7
+ data.tar.gz: f87ab041ef3e1d061a69d4e525481aa4203dce1f3957277daad053a1003b6dfdfa5d9aa6cfcab952029d0a4d5a84b21cb5001f566f25f3f50e9d738729d66c8e
@@ -1,3 +1,3 @@
1
1
  module Centrifuge
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -1,7 +1,4 @@
1
- /**
2
- * Centrifuge javascript client
3
- * v0.5.2
4
- */
1
+ // v0.7.0
5
2
  ;(function () {
6
3
  'use strict';
7
4
 
@@ -564,10 +561,102 @@
564
561
  }
565
562
  }
566
563
 
564
+ // http://krasimirtsonev.com/blog/article/Cross-browser-handling-of-Ajax-requests-in-absurdjs
565
+ var AJAX = {
566
+ request: function(url, method, ops) {
567
+ ops.data = ops.data || {};
568
+
569
+ var getParams = function(data, request_url) {
570
+ var arr = [], str;
571
+ for(var name in data) {
572
+ if (typeof data[name] === 'object') {
573
+ for (var i in data[name]) {
574
+ arr.push(name + '=' + encodeURIComponent(data[name][i]));
575
+ }
576
+ } else {
577
+ arr.push(name + '=' + encodeURIComponent(data[name]));
578
+ }
579
+ }
580
+ str = arr.join('&');
581
+ if(str != '') {
582
+ return request_url ? (request_url.indexOf('?') < 0 ? '?' + str : '&' + str) : str;
583
+ }
584
+ return '';
585
+ };
586
+ var api = {
587
+ host: {},
588
+ setHeaders: function(headers) {
589
+ for(var name in headers) {
590
+ this.xhr && this.xhr.setRequestHeader(name, headers[name]);
591
+ }
592
+ },
593
+ process: function(ops) {
594
+ var self = this;
595
+ this.xhr = null;
596
+ if (window.ActiveXObject) {
597
+ this.xhr = new ActiveXObject('Microsoft.XMLHTTP');
598
+ }
599
+ else if (window.XMLHttpRequest) {
600
+ this.xhr = new XMLHttpRequest();
601
+ }
602
+ if(this.xhr) {
603
+ this.xhr.onreadystatechange = function() {
604
+ if(self.xhr.readyState == 4 && self.xhr.status == 200) {
605
+ var result = self.xhr.responseText;
606
+ if (typeof JSON != 'undefined') {
607
+ result = JSON.parse(result);
608
+ } else {
609
+ throw "JSON undefined";
610
+ }
611
+ self.doneCallback && self.doneCallback.apply(self.host, [result, self.xhr]);
612
+ } else if(self.xhr.readyState == 4) {
613
+ self.failCallback && self.failCallback.apply(self.host, [self.xhr]);
614
+ }
615
+ self.alwaysCallback && self.alwaysCallback.apply(self.host, [self.xhr]);
616
+ }
617
+ }
618
+ if(method == 'get') {
619
+ this.xhr.open("GET", url + getParams(ops.data, url), true);
620
+ } else {
621
+ this.xhr.open(method, url, true);
622
+ this.setHeaders({
623
+ 'X-Requested-With': 'XMLHttpRequest',
624
+ 'Content-type': 'application/x-www-form-urlencoded'
625
+ });
626
+ }
627
+ if(ops.headers && typeof ops.headers == 'object') {
628
+ this.setHeaders(ops.headers);
629
+ }
630
+ setTimeout(function() {
631
+ method == 'get' ? self.xhr.send() : self.xhr.send(getParams(ops.data));
632
+ }, 20);
633
+ return this;
634
+ },
635
+ done: function(callback) {
636
+ this.doneCallback = callback;
637
+ return this;
638
+ },
639
+ fail: function(callback) {
640
+ this.failCallback = callback;
641
+ return this;
642
+ },
643
+ always: function(callback) {
644
+ this.alwaysCallback = callback;
645
+ return this;
646
+ }
647
+ };
648
+ return api.process(ops);
649
+ }
650
+ };
651
+
567
652
  function endsWith(value, suffix) {
568
653
  return value.indexOf(suffix, value.length - suffix.length) !== -1;
569
654
  }
570
655
 
656
+ function startsWith(value, prefix) {
657
+ return value.lastIndexOf(prefix, 0) === 0;
658
+ }
659
+
571
660
  function stripSlash(value) {
572
661
  if (value.substring(value.length - 1) == "/") {
573
662
  value = value.substring(0, value.length - 1);
@@ -608,10 +697,14 @@
608
697
  this._subscriptions = {};
609
698
  this._messages = [];
610
699
  this._isBatching = false;
700
+ this._isAuthBatching = false;
701
+ this._authChannels = {};
702
+ this._refreshTimeout = null;
611
703
  this._config = {
612
704
  retry: 3000,
613
705
  info: null,
614
706
  debug: false,
707
+ insecure: false,
615
708
  server: null,
616
709
  protocols_whitelist: [
617
710
  'websocket',
@@ -623,7 +716,12 @@
623
716
  'xhr-polling',
624
717
  'iframe-xhr-polling',
625
718
  'jsonp-polling'
626
- ]
719
+ ],
720
+ privateChannelPrefix: "$",
721
+ refreshEndpoint: "/centrifuge/refresh",
722
+ authEndpoint: "/centrifuge/auth",
723
+ authHeaders: {},
724
+ refreshHeaders: {}
627
725
  };
628
726
  if (options) {
629
727
  this.configure(options);
@@ -632,15 +730,15 @@
632
730
 
633
731
  extend(Centrifuge, EventEmitter);
634
732
 
635
- var centrifuge_proto = Centrifuge.prototype;
733
+ var centrifugeProto = Centrifuge.prototype;
636
734
 
637
- centrifuge_proto._debug = function () {
735
+ centrifugeProto._debug = function () {
638
736
  if (this._config.debug === true) {
639
737
  log('debug', arguments);
640
738
  }
641
739
  };
642
740
 
643
- centrifuge_proto._configure = function (configuration) {
741
+ centrifugeProto._configure = function (configuration) {
644
742
  this._debug('Configuring centrifuge object with', configuration);
645
743
 
646
744
  if (!configuration) {
@@ -653,20 +751,33 @@
653
751
  throw 'Missing required configuration parameter \'url\' specifying the Centrifuge server URL';
654
752
  }
655
753
 
656
- if (!this._config.token) {
657
- throw 'Missing required configuration parameter \'token\' specifying the sign of authorization request';
658
- }
659
-
660
754
  if (!this._config.project) {
661
755
  throw 'Missing required configuration parameter \'project\' specifying project ID in Centrifuge';
662
756
  }
663
757
 
664
758
  if (!this._config.user && this._config.user !== '') {
665
- throw 'Missing required configuration parameter \'user\' specifying user\'s unique ID in your application';
759
+ if (!this._config.insecure) {
760
+ throw 'Missing required configuration parameter \'user\' specifying user\'s unique ID in your application';
761
+ } else {
762
+ this._debug("user not found but this is OK for insecure mode - anonymous access will be used");
763
+ this._config.user = "";
764
+ }
666
765
  }
667
766
 
668
767
  if (!this._config.timestamp) {
669
- throw 'Missing required configuration parameter \'timestamp\'';
768
+ if (!this._config.insecure) {
769
+ throw 'Missing required configuration parameter \'timestamp\'';
770
+ } else {
771
+ this._debug("token not found but this is OK for insecure mode");
772
+ }
773
+ }
774
+
775
+ if (!this._config.token) {
776
+ if (!this._config.insecure) {
777
+ throw 'Missing required configuration parameter \'token\' specifying the sign of authorization request';
778
+ } else {
779
+ this._debug("timestamp not found but this is OK for insecure mode");
780
+ }
670
781
  }
671
782
 
672
783
  this._config.url = stripSlash(this._config.url);
@@ -680,30 +791,34 @@
680
791
  }
681
792
  };
682
793
 
683
- centrifuge_proto._setStatus = function (newStatus) {
794
+ centrifugeProto._setStatus = function (newStatus) {
684
795
  if (this._status !== newStatus) {
685
796
  this._debug('Status', this._status, '->', newStatus);
686
797
  this._status = newStatus;
687
798
  }
688
799
  };
689
800
 
690
- centrifuge_proto._isDisconnected = function () {
801
+ centrifugeProto._isDisconnected = function () {
691
802
  return this._isConnected() === false;
692
803
  };
693
804
 
694
- centrifuge_proto._isConnected = function () {
805
+ centrifugeProto._isConnected = function () {
695
806
  return this._status === 'connected';
696
807
  };
697
808
 
698
- centrifuge_proto._nextMessageId = function () {
809
+ centrifugeProto._isConnecting = function () {
810
+ return this._status === 'connecting';
811
+ };
812
+
813
+ centrifugeProto._nextMessageId = function () {
699
814
  return ++this._messageId;
700
815
  };
701
816
 
702
- centrifuge_proto._clearSubscriptions = function () {
817
+ centrifugeProto._clearSubscriptions = function () {
703
818
  this._subscriptions = {};
704
819
  };
705
820
 
706
- centrifuge_proto._send = function (messages) {
821
+ centrifugeProto._send = function (messages) {
707
822
  // We must be sure that the messages have a clientId.
708
823
  // This is not guaranteed since the handshake may take time to return
709
824
  // (and hence the clientId is not known yet) and the application
@@ -721,7 +836,11 @@
721
836
  }
722
837
  };
723
838
 
724
- centrifuge_proto._connect = function (callback) {
839
+ centrifugeProto._connect = function (callback) {
840
+
841
+ if (this.isConnected()) {
842
+ return;
843
+ }
725
844
 
726
845
  this._clientId = null;
727
846
 
@@ -759,18 +878,18 @@
759
878
  var centrifugeMessage = {
760
879
  'method': 'connect',
761
880
  'params': {
762
- 'token': self._config.token,
763
881
  'user': self._config.user,
764
- 'project': self._config.project,
765
- 'timestamp': self._config.timestamp
882
+ 'project': self._config.project
766
883
  }
767
884
  };
768
885
 
769
886
  if (self._config.info !== null) {
770
- self._debug("connect using additional info");
771
- centrifugeMessage['params']['info'] = self._config.info;
772
- } else {
773
- self._debug("connect without additional info");
887
+ centrifugeMessage["params"]["info"] = self._config.info;
888
+ }
889
+
890
+ if (!self._config.insecure) {
891
+ centrifugeMessage["params"]["timestamp"] = self._config.timestamp;
892
+ centrifugeMessage["params"]["token"] = self._config.token;
774
893
  }
775
894
  self.send(centrifugeMessage);
776
895
  };
@@ -799,7 +918,7 @@
799
918
  };
800
919
  };
801
920
 
802
- centrifuge_proto._disconnect = function () {
921
+ centrifugeProto._disconnect = function () {
803
922
  this._clientId = null;
804
923
  this._setStatus('disconnected');
805
924
  this._subscriptions = {};
@@ -807,7 +926,7 @@
807
926
  this._transport.close();
808
927
  };
809
928
 
810
- centrifuge_proto._getSubscription = function (channel) {
929
+ centrifugeProto._getSubscription = function (channel) {
811
930
  var subscription;
812
931
  subscription = this._subscriptions[channel];
813
932
  if (!subscription) {
@@ -816,37 +935,60 @@
816
935
  return subscription;
817
936
  };
818
937
 
819
- centrifuge_proto._removeSubscription = function (channel) {
938
+ centrifugeProto._removeSubscription = function (channel) {
820
939
  try {
821
940
  delete this._subscriptions[channel];
822
941
  } catch (e) {
823
942
  this._debug('nothing to delete for channel ', channel);
824
943
  }
944
+ try {
945
+ delete this._authChannels[channel];
946
+ } catch (e) {
947
+ this._debug('nothing to delete from authChannels for channel ', channel);
948
+ }
825
949
  };
826
950
 
827
- centrifuge_proto._connectResponse = function (message) {
951
+ centrifugeProto._connectResponse = function (message) {
952
+ if (this.isConnected()) {
953
+ return;
954
+ }
828
955
  if (message.error === null) {
829
- this._clientId = message.body;
956
+ if (!message.body) {
957
+ return;
958
+ }
959
+ var isExpired = message.body.expired;
960
+ if (isExpired) {
961
+ this.refresh();
962
+ return;
963
+ }
964
+ this._clientId = message.body.client;
830
965
  this._setStatus('connected');
831
966
  this.trigger('connect', [message]);
967
+ if (this._refreshTimeout) {
968
+ window.clearTimeout(this._refreshTimeout);
969
+ }
970
+ if (message.body.ttl !== null) {
971
+ var self = this;
972
+ this._refreshTimeout = window.setTimeout(function() {
973
+ self.refresh.call(self);
974
+ }, message.body.ttl * 1000);
975
+ }
832
976
  } else {
833
977
  this.trigger('error', [message]);
834
978
  this.trigger('connect:error', [message]);
835
979
  }
836
980
  };
837
981
 
838
- centrifuge_proto._disconnectResponse = function (message) {
982
+ centrifugeProto._disconnectResponse = function (message) {
839
983
  if (message.error === null) {
840
984
  this.disconnect();
841
- //this.trigger('disconnect', [message]);
842
- //this.trigger('disconnect:success', [message]);
843
985
  } else {
844
986
  this.trigger('error', [message]);
845
987
  this.trigger('disconnect:error', [message.error]);
846
988
  }
847
989
  };
848
990
 
849
- centrifuge_proto._subscribeResponse = function (message) {
991
+ centrifugeProto._subscribeResponse = function (message) {
850
992
  if (message.error !== null) {
851
993
  this.trigger('error', [message]);
852
994
  }
@@ -868,7 +1010,7 @@
868
1010
  }
869
1011
  };
870
1012
 
871
- centrifuge_proto._unsubscribeResponse = function (message) {
1013
+ centrifugeProto._unsubscribeResponse = function (message) {
872
1014
  var body = message.body;
873
1015
  var channel = body.channel;
874
1016
  var subscription = this.getSubscription(channel);
@@ -881,7 +1023,7 @@
881
1023
  }
882
1024
  };
883
1025
 
884
- centrifuge_proto._publishResponse = function (message) {
1026
+ centrifugeProto._publishResponse = function (message) {
885
1027
  var body = message.body;
886
1028
  var channel = body.channel;
887
1029
  var subscription = this.getSubscription(channel);
@@ -896,7 +1038,7 @@
896
1038
  }
897
1039
  };
898
1040
 
899
- centrifuge_proto._presenceResponse = function (message) {
1041
+ centrifugeProto._presenceResponse = function (message) {
900
1042
  var body = message.body;
901
1043
  var channel = body.channel;
902
1044
  var subscription = this.getSubscription(channel);
@@ -912,7 +1054,7 @@
912
1054
  }
913
1055
  };
914
1056
 
915
- centrifuge_proto._historyResponse = function (message) {
1057
+ centrifugeProto._historyResponse = function (message) {
916
1058
  var body = message.body;
917
1059
  var channel = body.channel;
918
1060
  var subscription = this.getSubscription(channel);
@@ -928,7 +1070,7 @@
928
1070
  }
929
1071
  };
930
1072
 
931
- centrifuge_proto._joinResponse = function(message) {
1073
+ centrifugeProto._joinResponse = function(message) {
932
1074
  var body = message.body;
933
1075
  var channel = body.channel;
934
1076
  var subscription = this.getSubscription(channel);
@@ -938,7 +1080,7 @@
938
1080
  subscription.trigger('join', [body]);
939
1081
  };
940
1082
 
941
- centrifuge_proto._leaveResponse = function(message) {
1083
+ centrifugeProto._leaveResponse = function(message) {
942
1084
  var body = message.body;
943
1085
  var channel = body.channel;
944
1086
  var subscription = this.getSubscription(channel);
@@ -948,7 +1090,7 @@
948
1090
  subscription.trigger('leave', [body]);
949
1091
  };
950
1092
 
951
- centrifuge_proto._messageResponse = function (message) {
1093
+ centrifugeProto._messageResponse = function (message) {
952
1094
  var body = message.body;
953
1095
  var channel = body.channel;
954
1096
  var subscription = this.getSubscription(channel);
@@ -958,7 +1100,19 @@
958
1100
  subscription.trigger('message', [body]);
959
1101
  };
960
1102
 
961
- centrifuge_proto._dispatchMessage = function(message) {
1103
+ centrifugeProto._refreshResponse = function (message) {
1104
+ if (this._refreshTimeout) {
1105
+ window.clearTimeout(this._refreshTimeout);
1106
+ }
1107
+ if (message.body.ttl !== null) {
1108
+ var self = this;
1109
+ self._refreshTimeout = window.setTimeout(function () {
1110
+ self.refresh.call(self);
1111
+ }, message.body.ttl * 1000);
1112
+ }
1113
+ };
1114
+
1115
+ centrifugeProto._dispatchMessage = function(message) {
962
1116
  if (message === undefined || message === null) {
963
1117
  return;
964
1118
  }
@@ -999,6 +1153,9 @@
999
1153
  break;
1000
1154
  case 'ping':
1001
1155
  break;
1156
+ case 'refresh':
1157
+ this._refreshResponse(message);
1158
+ break;
1002
1159
  case 'message':
1003
1160
  this._messageResponse(message);
1004
1161
  break;
@@ -1007,7 +1164,7 @@
1007
1164
  }
1008
1165
  };
1009
1166
 
1010
- centrifuge_proto._receive = function (data) {
1167
+ centrifugeProto._receive = function (data) {
1011
1168
  if (Object.prototype.toString.call(data) === Object.prototype.toString.call([])) {
1012
1169
  for (var i in data) {
1013
1170
  if (data.hasOwnProperty(i)) {
@@ -1020,13 +1177,13 @@
1020
1177
  }
1021
1178
  };
1022
1179
 
1023
- centrifuge_proto._flush = function() {
1180
+ centrifugeProto._flush = function() {
1024
1181
  var messages = this._messages.slice(0);
1025
1182
  this._messages = [];
1026
1183
  this._send(messages);
1027
1184
  };
1028
1185
 
1029
- centrifuge_proto._ping = function () {
1186
+ centrifugeProto._ping = function () {
1030
1187
  var centrifugeMessage = {
1031
1188
  "method": "ping",
1032
1189
  "params": {}
@@ -1036,27 +1193,29 @@
1036
1193
 
1037
1194
  /* PUBLIC API */
1038
1195
 
1039
- centrifuge_proto.getClientId = function () {
1196
+ centrifugeProto.getClientId = function () {
1040
1197
  return this._clientId;
1041
1198
  };
1042
1199
 
1043
- centrifuge_proto.isConnected = centrifuge_proto._isConnected;
1200
+ centrifugeProto.isConnected = centrifugeProto._isConnected;
1044
1201
 
1045
- centrifuge_proto.isDisconnected = centrifuge_proto._isDisconnected;
1202
+ centrifugeProto.isConnecting = centrifugeProto._isConnecting;
1046
1203
 
1047
- centrifuge_proto.configure = function (configuration) {
1204
+ centrifugeProto.isDisconnected = centrifugeProto._isDisconnected;
1205
+
1206
+ centrifugeProto.configure = function (configuration) {
1048
1207
  this._configure.call(this, configuration);
1049
1208
  };
1050
1209
 
1051
- centrifuge_proto.connect = centrifuge_proto._connect;
1210
+ centrifugeProto.connect = centrifugeProto._connect;
1052
1211
 
1053
- centrifuge_proto.disconnect = centrifuge_proto._disconnect;
1212
+ centrifugeProto.disconnect = centrifugeProto._disconnect;
1054
1213
 
1055
- centrifuge_proto.getSubscription = centrifuge_proto._getSubscription;
1214
+ centrifugeProto.getSubscription = centrifugeProto._getSubscription;
1056
1215
 
1057
- centrifuge_proto.ping = centrifuge_proto._ping;
1216
+ centrifugeProto.ping = centrifugeProto._ping;
1058
1217
 
1059
- centrifuge_proto.send = function (message) {
1218
+ centrifugeProto.send = function (message) {
1060
1219
  if (this._isBatching === true) {
1061
1220
  this._messages.push(message);
1062
1221
  } else {
@@ -1064,13 +1223,13 @@
1064
1223
  }
1065
1224
  };
1066
1225
 
1067
- centrifuge_proto.startBatching = function () {
1226
+ centrifugeProto.startBatching = function () {
1068
1227
  // start collecting messages without sending them to Centrifuge until flush
1069
1228
  // method called
1070
1229
  this._isBatching = true;
1071
1230
  };
1072
1231
 
1073
- centrifuge_proto.stopBatching = function(flush) {
1232
+ centrifugeProto.stopBatching = function(flush) {
1074
1233
  // stop collecting messages
1075
1234
  flush = flush || false;
1076
1235
  this._isBatching = false;
@@ -1079,11 +1238,96 @@
1079
1238
  }
1080
1239
  };
1081
1240
 
1082
- centrifuge_proto.flush = function() {
1241
+ centrifugeProto.flush = function() {
1242
+ // send batched messages to Centrifuge
1083
1243
  this._flush();
1084
1244
  };
1085
1245
 
1086
- centrifuge_proto.subscribe = function (channel, callback) {
1246
+ centrifugeProto.startAuthBatching = function() {
1247
+ // start collecting private channels to create bulk authentication
1248
+ // request to authEndpoint when stopAuthBatching will be called
1249
+ this._isAuthBatching = true;
1250
+ };
1251
+
1252
+ centrifugeProto.stopAuthBatching = function(callback) {
1253
+ // create request to authEndpoint with collected private channels
1254
+ // to ask if this client can subscribe on each channel
1255
+ this._isAuthBatching = false;
1256
+ var authChannels = this._authChannels;
1257
+ this._authChannels = {};
1258
+ var channels = [];
1259
+
1260
+ for (var channel in authChannels) {
1261
+ var subscription = this.getSubscription(channel);
1262
+ if (!subscription) {
1263
+ continue;
1264
+ }
1265
+ channels.push(channel);
1266
+ }
1267
+
1268
+ if (channels.length == 0) {
1269
+ if (callback) {
1270
+ callback();
1271
+ }
1272
+ return;
1273
+ }
1274
+
1275
+ var data = {
1276
+ "client": this.getClientId(),
1277
+ "channels": channels
1278
+ };
1279
+
1280
+ var self = this;
1281
+
1282
+ AJAX.request(this._config.authEndpoint, "post", {
1283
+ "headers": this._config.authHeaders,
1284
+ "data": data
1285
+ }).done(function(data) {
1286
+ for (var i in channels) {
1287
+ var channel = channels[i];
1288
+ var channelResponse = data[channel];
1289
+ if (!channelResponse) {
1290
+ // subscription:error
1291
+ self._subscribeResponse({
1292
+ "error": 404,
1293
+ "body": {
1294
+ "channel": channel
1295
+ }
1296
+ });
1297
+ continue;
1298
+ }
1299
+ if (!channelResponse.status || channelResponse.status === 200) {
1300
+ var centrifugeMessage = {
1301
+ "method": "subscribe",
1302
+ "params": {
1303
+ "channel": channel,
1304
+ "client": self.getClientId(),
1305
+ "info": channelResponse.info,
1306
+ "sign": channelResponse.sign
1307
+ }
1308
+ };
1309
+ self.send(centrifugeMessage);
1310
+ } else {
1311
+ self._subscribeResponse({
1312
+ "error": channelResponse.status,
1313
+ "body": {
1314
+ "channel": channel
1315
+ }
1316
+ });
1317
+ }
1318
+ }
1319
+ }).fail(function() {
1320
+ log("info", "authorization request failed");
1321
+ return false;
1322
+ }).always(function(){
1323
+ if (callback) {
1324
+ callback();
1325
+ }
1326
+ })
1327
+
1328
+ };
1329
+
1330
+ centrifugeProto.subscribe = function (channel, callback) {
1087
1331
 
1088
1332
  if (arguments.length < 1) {
1089
1333
  throw 'Illegal arguments number: required 1, got ' + arguments.length;
@@ -1107,7 +1351,7 @@
1107
1351
  }
1108
1352
  };
1109
1353
 
1110
- centrifuge_proto.unsubscribe = function (channel) {
1354
+ centrifugeProto.unsubscribe = function (channel) {
1111
1355
  if (arguments.length < 1) {
1112
1356
  throw 'Illegal arguments number: required 1, got ' + arguments.length;
1113
1357
  }
@@ -1124,7 +1368,7 @@
1124
1368
  }
1125
1369
  };
1126
1370
 
1127
- centrifuge_proto.publish = function (channel, data, callback) {
1371
+ centrifugeProto.publish = function (channel, data, callback) {
1128
1372
  var subscription = this.getSubscription(channel);
1129
1373
  if (subscription === null) {
1130
1374
  this._debug("subscription not found for channel " + channel);
@@ -1134,7 +1378,7 @@
1134
1378
  return subscription;
1135
1379
  };
1136
1380
 
1137
- centrifuge_proto.presence = function (channel, callback) {
1381
+ centrifugeProto.presence = function (channel, callback) {
1138
1382
  var subscription = this.getSubscription(channel);
1139
1383
  if (subscription === null) {
1140
1384
  this._debug("subscription not found for channel " + channel);
@@ -1144,7 +1388,7 @@
1144
1388
  return subscription;
1145
1389
  };
1146
1390
 
1147
- centrifuge_proto.history = function (channel, callback) {
1391
+ centrifugeProto.history = function (channel, callback) {
1148
1392
  var subscription = this.getSubscription(channel);
1149
1393
  if (subscription === null) {
1150
1394
  this._debug("subscription not found for channel " + channel);
@@ -1154,6 +1398,49 @@
1154
1398
  return subscription;
1155
1399
  };
1156
1400
 
1401
+ centrifugeProto.refresh = function () {
1402
+ // ask web app for connection parameters - project ID, user ID,
1403
+ // timestamp, info and token
1404
+ var self = this;
1405
+ this._debug('refresh');
1406
+ AJAX.request(this._config.refreshEndpoint, "post", {
1407
+ "headers": this._config.refreshHeaders,
1408
+ "data": {}
1409
+ }).done(function(data) {
1410
+ self._config.user = data.user;
1411
+ self._config.project = data.project;
1412
+ self._config.timestamp = data.timestamp;
1413
+ self._config.info = data.info;
1414
+ self._config.token = data.token;
1415
+ if (self._reconnect && self.isDisconnected()) {
1416
+ self.connect();
1417
+ } else {
1418
+ var centrifugeMessage = {
1419
+ "method": "refresh",
1420
+ "params": {
1421
+ 'user': self._config.user,
1422
+ 'project': self._config.project,
1423
+ 'timestamp': self._config.timestamp,
1424
+ 'info': self._config.info,
1425
+ 'token': self._config.token
1426
+ }
1427
+ };
1428
+ self.send(centrifugeMessage);
1429
+ }
1430
+ }).fail(function(xhr){
1431
+ // 403 or 500 - does not matter - if connection check activated then Centrifuge
1432
+ // will disconnect client eventually
1433
+ self._debug(xhr);
1434
+ self._debug("error getting connect parameters");
1435
+ if (self._refreshTimeout) {
1436
+ window.clearTimeout(self._refreshTimeout);
1437
+ }
1438
+ self._refreshTimeout = window.setTimeout(function(){
1439
+ self.refresh.call(self);
1440
+ }, 3000);
1441
+ });
1442
+ };
1443
+
1157
1444
  function Subscription(centrifuge, channel) {
1158
1445
  /**
1159
1446
  * The constructor for a centrifuge object, identified by an optional name.
@@ -1166,30 +1453,49 @@
1166
1453
 
1167
1454
  extend(Subscription, EventEmitter);
1168
1455
 
1169
- var sub_proto = Subscription.prototype;
1456
+ var subscriptionProto = Subscription.prototype;
1170
1457
 
1171
- sub_proto.getChannel = function () {
1458
+ subscriptionProto.getChannel = function () {
1172
1459
  return this.channel;
1173
1460
  };
1174
1461
 
1175
- sub_proto.getCentrifuge = function () {
1462
+ subscriptionProto.getCentrifuge = function () {
1176
1463
  return this._centrifuge;
1177
1464
  };
1178
1465
 
1179
- sub_proto.subscribe = function (callback) {
1466
+ subscriptionProto.subscribe = function (callback) {
1467
+ /*
1468
+ If channel name does not start with privateChannelPrefix - then we
1469
+ can just send subscription message to Centrifuge. If channel name
1470
+ starts with privateChannelPrefix - then this is a private channel
1471
+ and we should ask web application backend for permission first.
1472
+ */
1180
1473
  var centrifugeMessage = {
1181
1474
  "method": "subscribe",
1182
1475
  "params": {
1183
1476
  "channel": this.channel
1184
1477
  }
1185
1478
  };
1186
- this._centrifuge.send(centrifugeMessage);
1479
+
1480
+ if (startsWith(this.channel, this._centrifuge._config.privateChannelPrefix)) {
1481
+ // private channel
1482
+ if (this._centrifuge._isAuthBatching) {
1483
+ this._centrifuge._authChannels[this.channel] = true;
1484
+ } else {
1485
+ this._centrifuge.startAuthBatching();
1486
+ this.subscribe(callback);
1487
+ this._centrifuge.stopAuthBatching();
1488
+ }
1489
+ } else {
1490
+ this._centrifuge.send(centrifugeMessage);
1491
+ }
1492
+
1187
1493
  if (callback) {
1188
1494
  this.on('message', callback);
1189
1495
  }
1190
1496
  };
1191
1497
 
1192
- sub_proto.unsubscribe = function () {
1498
+ subscriptionProto.unsubscribe = function () {
1193
1499
  this._centrifuge._removeSubscription(this.channel);
1194
1500
  var centrifugeMessage = {
1195
1501
  "method": "unsubscribe",
@@ -1200,7 +1506,7 @@
1200
1506
  this._centrifuge.send(centrifugeMessage);
1201
1507
  };
1202
1508
 
1203
- sub_proto.publish = function (data, callback) {
1509
+ subscriptionProto.publish = function (data, callback) {
1204
1510
  var centrifugeMessage = {
1205
1511
  "method": "publish",
1206
1512
  "params": {
@@ -1214,7 +1520,7 @@
1214
1520
  this._centrifuge.send(centrifugeMessage);
1215
1521
  };
1216
1522
 
1217
- sub_proto.presence = function (callback) {
1523
+ subscriptionProto.presence = function (callback) {
1218
1524
  var centrifugeMessage = {
1219
1525
  "method": "presence",
1220
1526
  "params": {
@@ -1227,7 +1533,7 @@
1227
1533
  this._centrifuge.send(centrifugeMessage);
1228
1534
  };
1229
1535
 
1230
- sub_proto.history = function (callback) {
1536
+ subscriptionProto.history = function (callback) {
1231
1537
  var centrifugeMessage = {
1232
1538
  "method": "history",
1233
1539
  "params": {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: centrifuge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleg Bovykin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-28 00:00:00.000000000 Z
11
+ date: 2015-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient