rocket-js 0.0.1

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.
@@ -0,0 +1,40 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <link rel="stylesheet" href="/qunit.css">
5
+ <script src="/qunit.js"></script>
6
+ <script src="/jquery-1.4.2.min.js"></script>
7
+ <script src="/testing/rocket-<%= Rocket::JS.version %>.js"></script>
8
+ <script>
9
+
10
+ // The web-socket-js configuration.
11
+ WEB_SOCKET_SWF_LOCATION = 'rocket/WebSocketMain.swf';
12
+ WEB_SOCKET_DEBUG = false;
13
+
14
+ $(document).ready(function() {
15
+ // Logger...
16
+ Rocket.log = function(msg) { $("#log").append("<li>"+msg+"</li>") };
17
+
18
+ // Build new rocket
19
+ rocket = new Rocket('ws://localhost:9772', 'test_app');
20
+ // Subscribe a channel.
21
+ testChannel = rocket.subscribe('test-channel');
22
+ // Bind callback to event.
23
+ //testChannel.bind('test-event', function(data) {
24
+ // alert('hello!');
25
+ //});
26
+ });
27
+ </script>
28
+ </head>
29
+ <body>
30
+ <ul id="log">
31
+
32
+ <ul>
33
+ <!--
34
+ <h1 id="qunit-header">Pusher Tests</h1>
35
+ <h2 id="qunit-banner"></h2>
36
+ <h2 id="qunit-userAgent"></h2>
37
+ <ol id="qunit-tests"></ol>
38
+ -->
39
+ </body>
40
+ </html>
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'mocha'
3
+ require 'rspec'
4
+ require 'rocket-js'
5
+
6
+ RSpec.configure do |config|
7
+ config.mock_with :mocha
8
+ end
@@ -0,0 +1,127 @@
1
+ /**
2
+ * This object helps with channels management. Examples:
3
+ *
4
+ * channels = new Rocket.Channels();
5
+ * channels.add('test');
6
+ * channels.find('test');
7
+ * channels.remove('test');
8
+ * // ...
9
+ *
10
+ * @class
11
+ * @constructor
12
+ */
13
+ Rocket.Channels = function() {
14
+ this.all = {};
15
+ };
16
+
17
+ Rocket.Channels.prototype = {
18
+ /**
19
+ * Append new channel to the list of registered.
20
+ *
21
+ * @param {string} channelName
22
+ * @return Rocket.Channel
23
+ */
24
+ add: function(channelName) {
25
+ existingChannel = this.find(channelName)
26
+ if (!existingChannel) {
27
+ return (this.all[channelName] = new Rocket.Channel());
28
+ } else {
29
+ return existingChannel;
30
+ }
31
+ },
32
+
33
+ /**
34
+ * Returns channel with specified name when it exists.
35
+ *
36
+ * @param {string} channelName
37
+ * @return Rocket.Channel
38
+ */
39
+ find: function(channelName) {
40
+ return this.all[channelName];
41
+ },
42
+
43
+ /**
44
+ * Remove specified channel from the list.
45
+ *
46
+ * @param {string} channelName
47
+ * @return void
48
+ */
49
+ remove: function(channelName) {
50
+ delete this.all[channelName];
51
+ }
52
+ };
53
+
54
+ /**
55
+ * Single channel. It keeps eg. list of callbacks for all binded events,
56
+ * and helps with events dispatching.
57
+ *
58
+ * channel = new Rocket.Channel();
59
+ * channel.bind('my-event', function(data) {
60
+ * // do something with given data ...
61
+ * })
62
+ *
63
+ * @class
64
+ * @constructor
65
+ */
66
+ Rocket.Channel = function() {
67
+ this.callbacks = {};
68
+ this.globalCallbacks = [];
69
+ };
70
+
71
+ Rocket.Channel.prototype = {
72
+ /**
73
+ * Assign callback to given event. More than one callback can be assigned
74
+ * to one event, eg:
75
+ *
76
+ * channel.bind('my-event', function(data){ alert('first one!') });
77
+ * channel.bind('my-event', function(data){ alert('second one!') });
78
+ *
79
+ * @param {string} eventName
80
+ * @param {function} callback
81
+ * @return self
82
+ */
83
+ bind: function(eventName, callback) {
84
+ this.callbacks[eventName] = this.callbacks[eventName] || [];
85
+ this.callbacks[eventName].push(callback);
86
+ return this;
87
+ },
88
+
89
+ /**
90
+ * Creates global callback which will be invoked on all events just after
91
+ * processing callbacks assigned to it.
92
+ *
93
+ * channel.bindAll(function(event, data){ alert(event) });
94
+ *
95
+ * @param {function} callback
96
+ * @return self
97
+ */
98
+ bindAll: function(callback) {
99
+ this.globalCallbacks.push(callback);
100
+ return this;
101
+ },
102
+
103
+ /**
104
+ * Dispatch given event with passing data to all registered callbacks.
105
+ * All global callbacks will be called here too.
106
+ *
107
+ * channel.dispatch('my-event', {'hello': 'world'});
108
+ *
109
+ * @param {string} eventName
110
+ * @param {Object} eventData
111
+ * @return void
112
+ */
113
+ dispatch: function(eventName, eventData) {
114
+ var callbacks = this.callbacks[eventName]
115
+ if (callbacks) {
116
+ Rocket.log('Rocket : executing callbacks for ' + eventName)
117
+ for (var i = 0; i < callbacks.length; i++) {
118
+ callbacks[i](eventData);
119
+ }
120
+ } else if (!this.isGlobal) {
121
+ Rocket.log('Rocket : no callbacks for ' + eventName)
122
+ }
123
+ for (var i = 0; i < this.globalCallbacks.length; i++) {
124
+ this.globalCallbacks[i](eventName, eventData);
125
+ }
126
+ }
127
+ };
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Rocket base class. Examples:
3
+ *
4
+ * rocket = new Rocket('ws://host.com:8080', 'my-app'); // no trailing slash in url!
5
+ * rocket = new Rocket('wss://host.com:433', 'my-secured-app');
6
+ *
7
+ * @class
8
+ * @constructor
9
+ */
10
+ var Rocket = function(url, appID) {
11
+ this.socketId;
12
+ this.url = url + '/app/' + appID;
13
+ this.appID = appID;
14
+ this.channels = new Rocket.Channels();
15
+ this.retryCounter = 0;
16
+ this.isConnected = false;
17
+ this.globalChannel = new Rocket.Channel();
18
+ this.globalChannel.isGlobal = true
19
+ this.connect();
20
+
21
+ var self = this;
22
+
23
+ this.globalChannel.bind('rocket:connected', function(data) {
24
+ self.isConnected = true;
25
+ self.retryCounter = 0;
26
+ self.socketId = data.socket_id;
27
+ self.subscribeAll();
28
+ });
29
+
30
+ this.globalChannel.bind('rocket:error', function(data) {
31
+ //self.log("Rocket : error : " + data.message);
32
+ });
33
+ };
34
+
35
+ Rocket.prototype = {
36
+ /**
37
+ * Establish connection with specified web socket server.
38
+ *
39
+ * @return self
40
+ */
41
+ connect: function() {
42
+ Rocket.log('Rocket : connecting with ' + this.url);
43
+ this.allowReconnect = true
44
+ var self = this;
45
+
46
+ if (window["WebSocket"]) {
47
+ this.connection = new WebSocket(this.url);
48
+ this.connection.onmessage = function(msg) { self.onmessage(msg); };
49
+ this.connection.onclose = function() { self.onclose(); };
50
+ this.connection.onopen = function() { self.onopen(); };
51
+ } else {
52
+ Rocket.log("Rocket : can't establish connection")
53
+ this.connection = {};
54
+ this.onclose();
55
+ }
56
+ return this;
57
+ },
58
+
59
+ /**
60
+ * Close connection with web socket server and cleanup configuration.
61
+ *
62
+ * @return self
63
+ */
64
+ disconnect: function() {
65
+ Rocket.log('Rocket : disconnecting');
66
+ this.allowReconnect = false;
67
+ this.isConnected = false;
68
+ this.retryCount = 0;
69
+ this.connection.close();
70
+ return this;
71
+ },
72
+
73
+ /**
74
+ * Trying reconnect to socket after specified time.
75
+ *
76
+ * @param {integer} delay
77
+ * @return self
78
+ */
79
+ reconnect: function(delay) {
80
+ var self = this;
81
+ setTimeout(function(){ self.connect(); }, delay);
82
+ return this;
83
+ },
84
+
85
+ /**
86
+ * Searches for given channel and return it when exists.
87
+ *
88
+ * @param {string} channelName
89
+ * @return Rocket.Channel
90
+ */
91
+ channel: function(channelName) {
92
+ return this.channels.find(channelName)
93
+ },
94
+
95
+ /**
96
+ * Trigger given event by sending specified data.
97
+ *
98
+ * rocket.trigger('rocket:unsubscribe', { channel: 'my-channel' });
99
+ *
100
+ * @param {string} eventName
101
+ * @param {Object} data
102
+ * @return self
103
+ */
104
+ trigger: function(eventName, data) {
105
+ if (this.isConnected) {
106
+ var payload = JSON.stringify({ event: eventName, data: data });
107
+ Rocket.log("Rocket : triggering event : " + payload);
108
+ this.connection.send(payload);
109
+ } else {
110
+ Rocket.log("Rocket : not connected : can't trigger event " + eventName);
111
+ }
112
+ return this;
113
+ },
114
+
115
+ /**
116
+ * Subscribes specified channel and returns it.
117
+ *
118
+ * myChannel = rocket.subscribe('my-channel');
119
+ * myChannel.bind('my-event', function(data) {
120
+ * // do something with received data...
121
+ * });
122
+ *
123
+ * @param {string} channelName
124
+ * @return Rocket.Channel
125
+ */
126
+ subscribe: function(channelName) {
127
+ var channel = this.channels.add(channelName);
128
+ this.trigger('rocket:subscribe', { channel: channelName });
129
+ return channel;
130
+ },
131
+
132
+ /**
133
+ * Unsubscribes specified channel.
134
+ *
135
+ * myChannel = rocket.subscribe('my-channel');
136
+ * myChannel.bind('unsubscribe', function(data) {
137
+ * rocket.unsubscribe('my-channel');
138
+ * });
139
+ *
140
+ * @param {string} channelName
141
+ * @return self
142
+ */
143
+ unsubscribe: function(channelName) {
144
+ this.channels.remove(channelName);
145
+ this.trigger('rocket:unsubscribe', { channel: channelName });
146
+ return this;
147
+ },
148
+
149
+ /**
150
+ * Subscribe all registered channels. It's usualy used to subscribe all
151
+ * registered just after open connetion (or to re-subscribe after reconnect).
152
+ *
153
+ * @return void
154
+ */
155
+ subscribeAll: function() {
156
+ for (var channel in this.channels.all) {
157
+ if (this.channels.all.hasOwnProperty(channel)) {
158
+ this.subscribe(channel);
159
+ }
160
+ };
161
+ },
162
+
163
+ /**
164
+ * Callback invoked when conneciton is closed.
165
+ *
166
+ * @return void
167
+ */
168
+ onclose: function() {
169
+ Rocket.log("Rocket : socket closed");
170
+ this.globalChannel.dispatch('rocket:close', null);
171
+ var time = Rocket.reconnectDelay;
172
+
173
+ if (!(this.isConnected)) {
174
+ this.globalChannel.dispatch("rocket:disconnected", {});
175
+
176
+ if (Rocket.allowReconnect) {
177
+ Rocket.log('Pusher : reconnecting in 5 seconds...');
178
+ this.reconnect(time);
179
+ }
180
+ } else {
181
+ this.globalChannel("rocket:connection_failed", {});
182
+
183
+ if (this.retryCounter == 0){
184
+ time = 100;
185
+ }
186
+ this.retryCounter = this.retryCounter + 1
187
+ this.reconnect(time);
188
+ }
189
+ this.connected = false;
190
+ },
191
+
192
+ /**
193
+ * Callback invoked when connection is established.
194
+ *
195
+ * @return void
196
+ */
197
+ onopen: function() {
198
+ this.globalChannel.dispatch('rocket:open', null);
199
+ },
200
+
201
+ /**
202
+ * Callback invoked when message is received.
203
+ *
204
+ * @param {string} msg
205
+ * @return void
206
+ */
207
+ onmessage: function(msg) {
208
+ Rocket.log("Rocket : received message : " + msg.data)
209
+ var params = JSON.parse(msg.data);
210
+ var channel = params.channel ? this.channel(params.channel) : this.globalChannel;
211
+ channel.dispatch(params.event, params.data);
212
+ },
213
+ };
@@ -0,0 +1,50 @@
1
+ // The web-socket-js default configuration.
2
+
3
+ // Where your WebSocketMain.swf is located?
4
+ var WEB_SOCKET_SWF_LOCATION = 'WebSocketMain.swf';
5
+ // Run web socket in debug mode?
6
+ var WEB_SOCKET_DEBUG = false;
7
+
8
+ // Rocket defaults.
9
+
10
+ /**
11
+ * How many miliseconds system will wait until next reconnect try.
12
+ *
13
+ * @type integer
14
+ */
15
+ Rocket.reconnectDelay = 5000;
16
+
17
+ /**
18
+ * Allow socket reconnect?
19
+ *
20
+ * @type boolean
21
+ */
22
+ Rocket.allowReconnect = true;
23
+
24
+ /**
25
+ * Default logger. You can replace it with your own, eg.
26
+ *
27
+ * Rocket.log = function(msg) { console.log(msg) };
28
+ *
29
+ * @param {string} msg
30
+ * @return void
31
+ */
32
+ Rocket.log = function(msg) {
33
+ // nothing to do...
34
+ };
35
+
36
+ /**
37
+ * Default data parser. By default received data is treated as JSON. You
38
+ * can change this behaviour by replacing this parser.
39
+ *
40
+ * @param {string} data
41
+ * @return Object or string
42
+ */
43
+ Rocket.parser = function(data) {
44
+ try {
45
+ return JSON.parse(data);
46
+ } catch(e) {
47
+ Pusher.log("Rocket : data attribute not valid JSON - you may wish to implement your own Rocket.parser");
48
+ return data;
49
+ }
50
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Rocket JavaScript Library v<%= VERSION %>
3
+ *
4
+ * Copyright 2010, Araneo Ltd. <http://www.araneo.pl>
5
+ * Released under the MIT license.
6
+ *
7
+ * Author: Chris Kowalik <chris@nu7hat.ch>
8
+ */
9
+
10
+ /**
11
+ * This code is strongly inspired by and based on the Pusher JavaScript Library.
12
+ *
13
+ * Pusher JavaScript Library:
14
+ *
15
+ * Copyright 2010, New Bamboo <http://new-bamboo.co.uk/>
16
+ * Released under the MIT licence.
17
+ * Reference: http://pusherapp.com
18
+ *
19
+ * This library contains also code with the following licences:
20
+ *
21
+ * web_socket.js:
22
+ *
23
+ * Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
24
+ * License: New BSD License
25
+ * Reference: http://dev.w3.org/html5/websockets/
26
+ * Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol
27
+ *
28
+ * swfobject.js:
29
+ *
30
+ * SWFObject v2.2 <http://code.google.com/p/swfobject/>
31
+ * is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
32
+ *
33
+ * FABridge.js:
34
+ *
35
+ * Copyright 2006 Adobe Systems Incorporated
36
+ *
37
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
38
+ * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
39
+ * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
40
+ *
41
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
42
+ */