websocket-rails 0.1.4 → 0.1.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.
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -0
- data/lib/assets/javascripts/websocket_rails/channel.js.coffee +26 -0
- data/lib/assets/javascripts/websocket_rails/http_connection.js.coffee +52 -0
- data/lib/assets/javascripts/websocket_rails/websocket_connection.js.coffee +25 -0
- data/lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee +81 -0
- data/lib/websocket_rails/base_controller.rb +16 -0
- data/lib/websocket_rails/channel.rb +0 -1
- data/lib/websocket_rails/connection_adapters/web_socket.rb +2 -2
- data/lib/websocket_rails/connection_adapters.rb +14 -6
- data/lib/websocket_rails/connection_manager.rb +4 -4
- data/lib/websocket_rails/dispatcher.rb +2 -2
- data/lib/websocket_rails/event_queue.rb +20 -18
- data/lib/websocket_rails/version.rb +1 -1
- data/spec/dummy/log/test.log +74 -0
- data/spec/integration/connection_manager_spec.rb +1 -1
- data/spec/support/helper_methods.rb +4 -0
- data/spec/support/mock_web_socket.rb +4 -0
- data/spec/unit/connection_adapters/http_spec.rb +1 -1
- data/spec/unit/connection_adapters/web_socket_spec.rb +1 -1
- data/spec/unit/connection_adapters_spec.rb +2 -2
- data/spec/unit/connection_manager_spec.rb +3 -3
- metadata +8 -8
- data/lib/assets/javascripts/websocket_rails/channel.js +0 -35
- data/lib/assets/javascripts/websocket_rails/http_connection.js +0 -68
- data/lib/assets/javascripts/websocket_rails/websocket_connection.js +0 -38
- data/lib/assets/javascripts/websocket_rails/websocket_rails.js +0 -100
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# WebsocketRails Change Log
|
2
2
|
|
3
|
+
## Version 0.1.5
|
4
|
+
|
5
|
+
July 3 2012
|
6
|
+
|
7
|
+
* Fixed bug in JavaScript client that caused Channels not to dispatch
|
8
|
+
correctly.
|
9
|
+
* Rewrote JavaScript client in CoffeeScript.
|
10
|
+
* Created project Wiki
|
11
|
+
|
3
12
|
## Version 0.1.4
|
4
13
|
|
5
14
|
June 30 2012
|
data/Gemfile
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
###
|
2
|
+
The channel object is returned when you subscribe to a channel.
|
3
|
+
|
4
|
+
For instance:
|
5
|
+
var dispatcher = new WebSocketRails('localhost:3000/websocket');
|
6
|
+
var awesome_channel = dispatcher.subscribe('awesome_channel');
|
7
|
+
awesome_channel.bind('event', function(data) { console.log('channel event!'); });
|
8
|
+
awesome_channel.trigger('awesome_event', awesome_object);
|
9
|
+
###
|
10
|
+
class WebSocketRails.Channel
|
11
|
+
|
12
|
+
constructor: (@name,@dispatcher) ->
|
13
|
+
@dispatcher.trigger 'websocket_rails.subscribe', {channel: @name}
|
14
|
+
@callbacks = {}
|
15
|
+
|
16
|
+
bind: (event_name, callback) =>
|
17
|
+
@callbacks[event_name] ?= []
|
18
|
+
@callbacks[event_name].push callback
|
19
|
+
|
20
|
+
trigger: (event_name, message) =>
|
21
|
+
@dispatcher.trigger_channel @name, event_name, message
|
22
|
+
|
23
|
+
dispatch: (event_name, message) =>
|
24
|
+
return unless @callbacks[event_name]?
|
25
|
+
for callback in @callbacks[event_name]
|
26
|
+
callback message
|
@@ -0,0 +1,52 @@
|
|
1
|
+
###
|
2
|
+
HTTP Interface for the WebSocketRails client.
|
3
|
+
###
|
4
|
+
class WebSocketRails.HttpConnection
|
5
|
+
httpFactories: -> [
|
6
|
+
-> new XMLHttpRequest(),
|
7
|
+
-> new ActiveXObject("Msxml2.XMLHTTP"),
|
8
|
+
-> new ActiveXObject("Msxml3.XMLHTTP"),
|
9
|
+
-> new ActiveXObject("Microsoft.XMLHTTP")
|
10
|
+
]
|
11
|
+
|
12
|
+
createXMLHttpObject: =>
|
13
|
+
xmlhttp = false
|
14
|
+
factories = @httpFactories()
|
15
|
+
for factory in factories
|
16
|
+
try
|
17
|
+
xmlhttp = factory()
|
18
|
+
catch e
|
19
|
+
continue
|
20
|
+
break
|
21
|
+
xmlhttp
|
22
|
+
|
23
|
+
constructor: (@url, @dispatcher) ->
|
24
|
+
@_conn = @createXMLHttpObject()
|
25
|
+
@last_pos = 0
|
26
|
+
@_conn.onreadystatechange = @parse_stream
|
27
|
+
@_conn.open "GET", "/websocket", true
|
28
|
+
@_conn.send()
|
29
|
+
|
30
|
+
parse_stream: =>
|
31
|
+
if @_conn.readyState == 3
|
32
|
+
data = @_conn.responseText.substring @last_pos
|
33
|
+
@last_pos = @_conn.responseText.length
|
34
|
+
decoded_data = JSON.parse data
|
35
|
+
@dispatcher.new_message decoded_data
|
36
|
+
|
37
|
+
trigger: (event_name, data, connection_id) =>
|
38
|
+
payload = JSON.stringify [event_name, data]
|
39
|
+
@post_data connection_id, payload
|
40
|
+
|
41
|
+
trigger_channel: (channel_name, event_name, data, connection_id) =>
|
42
|
+
payload = JSON.stringify [channel_name, event_name, data]
|
43
|
+
@post_data connection_id, payload
|
44
|
+
|
45
|
+
post_data: (connection_id, payload) ->
|
46
|
+
$.ajax "/websocket",
|
47
|
+
type: 'POST'
|
48
|
+
data:
|
49
|
+
client_id: connection_id
|
50
|
+
data: payload
|
51
|
+
success: ->
|
52
|
+
console.log "success"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
###
|
2
|
+
WebSocket Interface for the WebSocketRails client.
|
3
|
+
###
|
4
|
+
class WebSocketRails.WebSocketConnection
|
5
|
+
|
6
|
+
constructor: (@url,@dispatcher) ->
|
7
|
+
@_conn = new WebSocket("ws://#{@url}")
|
8
|
+
@_conn.onmessage = @on_message
|
9
|
+
@_conn.onclose = @on_close
|
10
|
+
|
11
|
+
trigger: (event_name, data, connection_id) =>
|
12
|
+
payload = JSON.stringify [event_name, data]
|
13
|
+
@_conn.send payload
|
14
|
+
|
15
|
+
trigger_channel: (channel_name, event_name, data, connection_id) =>
|
16
|
+
payload = JSON.stringify [channel_name, event_name, data]
|
17
|
+
@_conn.send payload
|
18
|
+
|
19
|
+
on_message: (event) =>
|
20
|
+
data = JSON.parse event.data
|
21
|
+
console.log data
|
22
|
+
@dispatcher.new_message data
|
23
|
+
|
24
|
+
on_close: (event) =>
|
25
|
+
@dispatcher.dispatch 'connection_close', {}
|
@@ -0,0 +1,81 @@
|
|
1
|
+
###
|
2
|
+
WebsocketRails JavaScript Client
|
3
|
+
|
4
|
+
Setting up the dispatcher:
|
5
|
+
var dispatcher = new WebSocketRails('localhost:3000');
|
6
|
+
dispatcher.on_open = function() {
|
7
|
+
// trigger a server event immediately after opening connection
|
8
|
+
dispatcher.trigger('new_user',{user_name: 'guest'});
|
9
|
+
})
|
10
|
+
|
11
|
+
Triggering a new event on the server
|
12
|
+
dispatcherer.trigger('event_name',object_to_be_serialized_to_json);
|
13
|
+
|
14
|
+
Listening for new events from the server
|
15
|
+
dispatcher.bind('event_name', function(data) {
|
16
|
+
console.log(data.user_name);
|
17
|
+
});
|
18
|
+
###
|
19
|
+
class window.WebSocketRails
|
20
|
+
constructor: (@url, @use_websockets = true) ->
|
21
|
+
@state = 'connecting'
|
22
|
+
@callbacks = {}
|
23
|
+
@channels = {}
|
24
|
+
|
25
|
+
unless @supports_websockets() and @use_websockets
|
26
|
+
@_conn = new WebSocketRails.HttpConnection url, @
|
27
|
+
else
|
28
|
+
@_conn = new WebSocketRails.WebSocketConnection url, @
|
29
|
+
|
30
|
+
@_conn.new_message = @new_message
|
31
|
+
|
32
|
+
new_message: (data) =>
|
33
|
+
for socket_message in data
|
34
|
+
if socket_message.length > 2
|
35
|
+
event_name = socket_message[1]
|
36
|
+
message = socket_message[2]
|
37
|
+
@dispatch_channel socket_message...
|
38
|
+
else
|
39
|
+
event_name = socket_message[0]
|
40
|
+
message = socket_message[1]
|
41
|
+
@dispatch socket_message...
|
42
|
+
|
43
|
+
if @state == 'connecting' and event_name == 'client_connected'
|
44
|
+
@connection_established message
|
45
|
+
|
46
|
+
connection_established: (data) =>
|
47
|
+
@state = 'connected'
|
48
|
+
@connection_id = data.connection_id
|
49
|
+
if @on_open?
|
50
|
+
@on_open(data)
|
51
|
+
|
52
|
+
bind: (event_name, callback) =>
|
53
|
+
@callbacks[event_name] ?= []
|
54
|
+
@callbacks[event_name].push callback
|
55
|
+
|
56
|
+
trigger: (event_name, data) =>
|
57
|
+
@_conn.trigger event_name, data, @connection_id
|
58
|
+
|
59
|
+
dispatch: (event_name, data) =>
|
60
|
+
return unless @callbacks[event_name]?
|
61
|
+
for callback in @callbacks[event_name]
|
62
|
+
callback data
|
63
|
+
|
64
|
+
subscribe: (channel_name) =>
|
65
|
+
unless @channels[channel_name]?
|
66
|
+
channel = new WebSocketRails.Channel channel_name, @
|
67
|
+
@channels[channel_name] = channel
|
68
|
+
channel
|
69
|
+
else
|
70
|
+
@channels[channel_name]
|
71
|
+
|
72
|
+
trigger_channel: (channel, event_name, data) =>
|
73
|
+
@_conn.trigger_channel channel, event_name, @connection_id
|
74
|
+
|
75
|
+
dispatch_channel: (channel, event_name, message) =>
|
76
|
+
return unless @channels[channel]?
|
77
|
+
@channels[channel].dispatch event_name, message
|
78
|
+
|
79
|
+
supports_websockets: =>
|
80
|
+
(typeof(WebSocket) == "function" or typeof(WebSocket) == "object")
|
81
|
+
|
@@ -102,6 +102,10 @@ module WebsocketRails
|
|
102
102
|
event = Event.new( event_name, message, options )
|
103
103
|
@_dispatcher.broadcast_message event if @_dispatcher.respond_to?(:broadcast_message)
|
104
104
|
end
|
105
|
+
|
106
|
+
def request
|
107
|
+
@_request
|
108
|
+
end
|
105
109
|
|
106
110
|
# Provides access to the {DataStore} for the current controller. The {DataStore} provides convenience
|
107
111
|
# methods for keeping track of data associated with active connections. See it's documentation for
|
@@ -123,6 +127,18 @@ module WebsocketRails
|
|
123
127
|
instance_eval( &observer )
|
124
128
|
end
|
125
129
|
end
|
130
|
+
|
131
|
+
def delegate
|
132
|
+
connection.controller_delegate
|
133
|
+
end
|
134
|
+
|
135
|
+
def method_missing(method,*args,&block)
|
136
|
+
if delegate.respond_to? method
|
137
|
+
delegate.send method, *args, &block
|
138
|
+
else
|
139
|
+
super
|
140
|
+
end
|
141
|
+
end
|
126
142
|
|
127
143
|
end
|
128
144
|
end
|
@@ -6,9 +6,9 @@ module WebsocketRails
|
|
6
6
|
Faye::WebSocket.websocket?( env )
|
7
7
|
end
|
8
8
|
|
9
|
-
def initialize(
|
9
|
+
def initialize(request,dispatcher)
|
10
10
|
super
|
11
|
-
@connection = Faye::WebSocket.new( env )
|
11
|
+
@connection = Faye::WebSocket.new( request.env )
|
12
12
|
@connection.onmessage = method(:on_message)
|
13
13
|
@connection.onerror = method(:on_error)
|
14
14
|
@connection.onclose = method(:on_close)
|
@@ -9,9 +9,9 @@ module WebsocketRails
|
|
9
9
|
@adapters.unshift adapter
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.establish_connection(
|
13
|
-
adapter = adapters.detect { |a| a.accepts?( env ) } || (raise InvalidConnectionError)
|
14
|
-
adapter.new
|
12
|
+
def self.establish_connection(request,dispatcher)
|
13
|
+
adapter = adapters.detect { |a| a.accepts?( request.env ) } || (raise InvalidConnectionError)
|
14
|
+
adapter.new request, dispatcher
|
15
15
|
end
|
16
16
|
|
17
17
|
class Base
|
@@ -24,12 +24,16 @@ module WebsocketRails
|
|
24
24
|
ConnectionAdapters.register adapter
|
25
25
|
end
|
26
26
|
|
27
|
-
attr_reader :dispatcher, :queue
|
27
|
+
attr_reader :dispatcher, :queue, :env, :request
|
28
28
|
|
29
|
-
def initialize(
|
30
|
-
@env = env
|
29
|
+
def initialize(request,dispatcher)
|
30
|
+
@env = request.env.dup
|
31
|
+
@request = request
|
31
32
|
@queue = EventQueue.new
|
32
33
|
@dispatcher = dispatcher
|
34
|
+
@delegate = DelegationController.new
|
35
|
+
@delegate.instance_variable_set(:@_env,request.env)
|
36
|
+
@delegate.instance_variable_set(:@_request,request)
|
33
37
|
end
|
34
38
|
|
35
39
|
def on_open(data=nil)
|
@@ -87,6 +91,10 @@ module WebsocketRails
|
|
87
91
|
object_id.to_i
|
88
92
|
end
|
89
93
|
|
94
|
+
def controller_delegate
|
95
|
+
@delegate
|
96
|
+
end
|
97
|
+
|
90
98
|
private
|
91
99
|
|
92
100
|
def dispatch(event)
|
@@ -26,12 +26,12 @@ module WebsocketRails
|
|
26
26
|
|
27
27
|
# Primary entry point for the Rack application
|
28
28
|
def call(env)
|
29
|
-
request =
|
29
|
+
request = ActionDispatch::Request.new env
|
30
30
|
|
31
31
|
if request.post?
|
32
32
|
response = parse_incoming_event request.params
|
33
33
|
else
|
34
|
-
response = open_connection
|
34
|
+
response = open_connection request
|
35
35
|
end
|
36
36
|
|
37
37
|
response
|
@@ -53,8 +53,8 @@ module WebsocketRails
|
|
53
53
|
|
54
54
|
# Opens a persistent connection using the appropriate {ConnectionAdapter}. Stores
|
55
55
|
# active connections in the {connections} array.
|
56
|
-
def open_connection(
|
57
|
-
connection = ConnectionAdapters.establish_connection(
|
56
|
+
def open_connection(request)
|
57
|
+
connection = ConnectionAdapters.establish_connection( request, dispatcher )
|
58
58
|
connections << connection
|
59
59
|
connection.rack_response
|
60
60
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
#require 'actionpack/action_dispatch/request'
|
2
|
+
|
1
3
|
module WebsocketRails
|
2
4
|
class Dispatcher
|
3
5
|
|
@@ -27,12 +29,10 @@ module WebsocketRails
|
|
27
29
|
end
|
28
30
|
|
29
31
|
def send_message(event)
|
30
|
-
puts "sending message: #{event.serialize}"
|
31
32
|
event.connection.trigger event
|
32
33
|
end
|
33
34
|
|
34
35
|
def broadcast_message(event)
|
35
|
-
puts "broadcasting message: #{event.serialize}"
|
36
36
|
connection_manager.connections.map do |connection|
|
37
37
|
connection.trigger event
|
38
38
|
end
|
@@ -1,27 +1,29 @@
|
|
1
|
-
|
1
|
+
module WebsocketRails
|
2
|
+
class EventQueue
|
2
3
|
|
3
|
-
|
4
|
+
attr_reader :queue
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
def initialize
|
7
|
+
@queue = []
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def enqueue(event)
|
11
|
+
@queue << event
|
12
|
+
end
|
13
|
+
alias :<< :enqueue
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
def last
|
16
|
+
@queue.last
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def flush(&block)
|
20
|
+
unless block.nil?
|
21
|
+
@queue.each do |item|
|
22
|
+
block.call item
|
23
|
+
end
|
22
24
|
end
|
25
|
+
@queue = []
|
23
26
|
end
|
24
|
-
@queue = []
|
25
|
-
end
|
26
27
|
|
28
|
+
end
|
27
29
|
end
|
data/spec/dummy/log/test.log
CHANGED
@@ -632,3 +632,77 @@ Connecting to database specified by database.yml
|
|
632
632
|
Connecting to database specified by database.yml
|
633
633
|
Connecting to database specified by database.yml
|
634
634
|
Connecting to database specified by database.yml
|
635
|
+
Connecting to database specified by database.yml
|
636
|
+
Connecting to database specified by database.yml
|
637
|
+
Connecting to database specified by database.yml
|
638
|
+
Connecting to database specified by database.yml
|
639
|
+
Connecting to database specified by database.yml
|
640
|
+
Connecting to database specified by database.yml
|
641
|
+
Connecting to database specified by database.yml
|
642
|
+
Connecting to database specified by database.yml
|
643
|
+
Connecting to database specified by database.yml
|
644
|
+
Connecting to database specified by database.yml
|
645
|
+
Connecting to database specified by database.yml
|
646
|
+
Connecting to database specified by database.yml
|
647
|
+
Connecting to database specified by database.yml
|
648
|
+
Connecting to database specified by database.yml
|
649
|
+
Connecting to database specified by database.yml
|
650
|
+
Connecting to database specified by database.yml
|
651
|
+
Connecting to database specified by database.yml
|
652
|
+
Connecting to database specified by database.yml
|
653
|
+
Connecting to database specified by database.yml
|
654
|
+
Connecting to database specified by database.yml
|
655
|
+
Connecting to database specified by database.yml
|
656
|
+
Connecting to database specified by database.yml
|
657
|
+
Connecting to database specified by database.yml
|
658
|
+
Connecting to database specified by database.yml
|
659
|
+
Connecting to database specified by database.yml
|
660
|
+
Connecting to database specified by database.yml
|
661
|
+
Connecting to database specified by database.yml
|
662
|
+
Connecting to database specified by database.yml
|
663
|
+
Connecting to database specified by database.yml
|
664
|
+
Connecting to database specified by database.yml
|
665
|
+
Connecting to database specified by database.yml
|
666
|
+
Connecting to database specified by database.yml
|
667
|
+
Connecting to database specified by database.yml
|
668
|
+
Connecting to database specified by database.yml
|
669
|
+
Connecting to database specified by database.yml
|
670
|
+
Connecting to database specified by database.yml
|
671
|
+
Connecting to database specified by database.yml
|
672
|
+
Connecting to database specified by database.yml
|
673
|
+
Connecting to database specified by database.yml
|
674
|
+
Connecting to database specified by database.yml
|
675
|
+
Connecting to database specified by database.yml
|
676
|
+
Connecting to database specified by database.yml
|
677
|
+
Connecting to database specified by database.yml
|
678
|
+
Connecting to database specified by database.yml
|
679
|
+
Connecting to database specified by database.yml
|
680
|
+
Connecting to database specified by database.yml
|
681
|
+
Connecting to database specified by database.yml
|
682
|
+
Connecting to database specified by database.yml
|
683
|
+
Connecting to database specified by database.yml
|
684
|
+
Connecting to database specified by database.yml
|
685
|
+
Connecting to database specified by database.yml
|
686
|
+
Connecting to database specified by database.yml
|
687
|
+
Connecting to database specified by database.yml
|
688
|
+
Connecting to database specified by database.yml
|
689
|
+
Connecting to database specified by database.yml
|
690
|
+
Connecting to database specified by database.yml
|
691
|
+
Connecting to database specified by database.yml
|
692
|
+
Connecting to database specified by database.yml
|
693
|
+
Connecting to database specified by database.yml
|
694
|
+
Connecting to database specified by database.yml
|
695
|
+
Connecting to database specified by database.yml
|
696
|
+
Connecting to database specified by database.yml
|
697
|
+
Connecting to database specified by database.yml
|
698
|
+
Connecting to database specified by database.yml
|
699
|
+
Connecting to database specified by database.yml
|
700
|
+
Connecting to database specified by database.yml
|
701
|
+
Connecting to database specified by database.yml
|
702
|
+
Connecting to database specified by database.yml
|
703
|
+
Connecting to database specified by database.yml
|
704
|
+
Connecting to database specified by database.yml
|
705
|
+
Connecting to database specified by database.yml
|
706
|
+
Connecting to database specified by database.yml
|
707
|
+
Connecting to database specified by database.yml
|
708
|
+
Connecting to database specified by database.yml
|
@@ -70,7 +70,7 @@ module WebsocketRails
|
|
70
70
|
it "should subscribe the connection to the correct channel" do
|
71
71
|
@server.call( env )
|
72
72
|
channel = WebsocketRails[:awesome_channel]
|
73
|
-
|
73
|
+
channel.should_receive(:subscribe).once.with(socket)
|
74
74
|
Channel.any_instance.stub(:subscribe).and_raise(Exception)
|
75
75
|
socket.on_message encoded_message
|
76
76
|
end
|
@@ -4,7 +4,7 @@ module WebsocketRails
|
|
4
4
|
module ConnectionAdapters
|
5
5
|
describe Http do
|
6
6
|
|
7
|
-
subject { Http.new(
|
7
|
+
subject { Http.new( mock_request, double('Dispatcher').as_null_object ) }
|
8
8
|
|
9
9
|
it "should be a subclass of ConnectionAdapters::Base" do
|
10
10
|
subject.class.superclass.should == ConnectionAdapters::Base
|
@@ -8,7 +8,7 @@ module WebsocketRails
|
|
8
8
|
before do
|
9
9
|
@socket = MockWebSocket.new
|
10
10
|
Faye::WebSocket.stub(:new).and_return(@socket)
|
11
|
-
@adapter = WebSocket.new(
|
11
|
+
@adapter = WebSocket.new( mock_request, double('Dispatcher').as_null_object )
|
12
12
|
end
|
13
13
|
|
14
14
|
context "#send" do
|
@@ -19,7 +19,7 @@ module WebsocketRails
|
|
19
19
|
|
20
20
|
context ".establish_connection" do
|
21
21
|
it "should return the correct connection adapter instance" do
|
22
|
-
adapter = ConnectionAdapters.establish_connection(
|
22
|
+
adapter = ConnectionAdapters.establish_connection( mock_request, double('Dispatcher').as_null_object )
|
23
23
|
adapter.class.should == ConnectionAdapters::Test
|
24
24
|
end
|
25
25
|
end
|
@@ -32,7 +32,7 @@ module WebsocketRails
|
|
32
32
|
let(:channel_manager) { double('ChannelManager').as_null_object }
|
33
33
|
let(:event) { double('Event').as_null_object }
|
34
34
|
before { Event.stub(:new_from_json).and_return(event) }
|
35
|
-
subject { Base.new(
|
35
|
+
subject { Base.new( mock_request, dispatcher ) }
|
36
36
|
|
37
37
|
context "new adapters" do
|
38
38
|
it "should register themselves in the adapters array when inherited" do
|
@@ -17,7 +17,7 @@ module WebsocketRails
|
|
17
17
|
|
18
18
|
before(:each) do
|
19
19
|
ConnectionAdapters::Base.any_instance.stub(:send)
|
20
|
-
@mock_socket = ConnectionAdapters::Base.new(
|
20
|
+
@mock_socket = ConnectionAdapters::Base.new(mock_request,dispatcher)
|
21
21
|
ConnectionAdapters.stub(:establish_connection).and_return(@mock_socket)
|
22
22
|
end
|
23
23
|
|
@@ -38,7 +38,7 @@ module WebsocketRails
|
|
38
38
|
|
39
39
|
context "new POST event" do
|
40
40
|
before(:each) do
|
41
|
-
@mock_http = ConnectionAdapters::Http.new(
|
41
|
+
@mock_http = ConnectionAdapters::Http.new(mock_request,dispatcher)
|
42
42
|
app.connections << @mock_http
|
43
43
|
end
|
44
44
|
|
@@ -50,7 +50,7 @@ module WebsocketRails
|
|
50
50
|
|
51
51
|
context "open connections" do
|
52
52
|
before(:each) do
|
53
|
-
ConnectionAdapters.stub(:establish_connection).and_return(@mock_socket,ConnectionAdapters::Base.new(
|
53
|
+
ConnectionAdapters.stub(:establish_connection).and_return(@mock_socket,ConnectionAdapters::Base.new(mock_request,dispatcher))
|
54
54
|
4.times { open_connection }
|
55
55
|
end
|
56
56
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: websocket-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-07-04 00:00:00.000000000Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rails
|
@@ -117,11 +117,11 @@ executables:
|
|
117
117
|
extensions: []
|
118
118
|
extra_rdoc_files: []
|
119
119
|
files:
|
120
|
-
- lib/assets/javascripts/websocket_rails/channel.js
|
121
|
-
- lib/assets/javascripts/websocket_rails/http_connection.js
|
120
|
+
- lib/assets/javascripts/websocket_rails/channel.js.coffee
|
121
|
+
- lib/assets/javascripts/websocket_rails/http_connection.js.coffee
|
122
122
|
- lib/assets/javascripts/websocket_rails/main.js
|
123
|
-
- lib/assets/javascripts/websocket_rails/websocket_connection.js
|
124
|
-
- lib/assets/javascripts/websocket_rails/websocket_rails.js
|
123
|
+
- lib/assets/javascripts/websocket_rails/websocket_connection.js.coffee
|
124
|
+
- lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee
|
125
125
|
- lib/generators/websocket_rails/install/install_generator.rb
|
126
126
|
- lib/generators/websocket_rails/install/templates/events.rb
|
127
127
|
- lib/websocket-rails.rb
|
@@ -213,7 +213,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
213
213
|
version: '0'
|
214
214
|
segments:
|
215
215
|
- 0
|
216
|
-
hash: -
|
216
|
+
hash: -3272086084276613534
|
217
217
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
218
218
|
none: false
|
219
219
|
requirements:
|
@@ -222,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
222
|
version: '0'
|
223
223
|
segments:
|
224
224
|
- 0
|
225
|
-
hash: -
|
225
|
+
hash: -3272086084276613534
|
226
226
|
requirements: []
|
227
227
|
rubyforge_project: websocket-rails
|
228
228
|
rubygems_version: 1.8.19
|
@@ -1,35 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* The channel object is returned when you subscribe to a channel.
|
3
|
-
*
|
4
|
-
* For instance:
|
5
|
-
* var dispatcher = new WebSocketRails('localhost:3000/websocket');
|
6
|
-
* var awesome_channel = dispatcher.subscribe('awesome_channel');
|
7
|
-
* awesome_channel.bind('event', function() { console.log('channel event!'); });
|
8
|
-
* awesome_channel.trigger('awesome_event', awesome_object);
|
9
|
-
*/
|
10
|
-
|
11
|
-
WebSocketRails.Channel = function(name,dispatcher) {
|
12
|
-
var that = this;
|
13
|
-
that.name = name;
|
14
|
-
|
15
|
-
dispatcher.trigger('websocket_rails.subscribe',{channel: name})
|
16
|
-
|
17
|
-
var callbacks = {};
|
18
|
-
|
19
|
-
that.bind = function(event_name, callback) {
|
20
|
-
callbacks[event_name] = callbacks[event_name] || [];
|
21
|
-
callbacks[event_name].push(callback);
|
22
|
-
}
|
23
|
-
|
24
|
-
that.trigger = function(event_name, message) {
|
25
|
-
dispatcher.trigger_channel(that.name,event_name,message);
|
26
|
-
}
|
27
|
-
|
28
|
-
that.dispatch = function(event_name, message) {
|
29
|
-
var chain = callbacks[event_name];
|
30
|
-
if (typeof chain == 'undefined') return;
|
31
|
-
for(var i = 0; i < chain.length; i++) {
|
32
|
-
chain[i]( message );
|
33
|
-
}
|
34
|
-
}
|
35
|
-
}
|
@@ -1,68 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* HTTP Interface for the WebSocketRails client.
|
3
|
-
*/
|
4
|
-
WebSocketRails.HttpConnection = function(url,dispatcher){
|
5
|
-
var that = this,
|
6
|
-
conn = WebSocketRails.createXMLHttpObject(),
|
7
|
-
lastPos = 0;
|
8
|
-
|
9
|
-
conn.onreadystatechange = function() {
|
10
|
-
if (conn.readyState == 3) {
|
11
|
-
var data = conn.responseText.substring(lastPos);
|
12
|
-
lastPos = conn.responseText.length;
|
13
|
-
|
14
|
-
console.log('raw data: '+data);
|
15
|
-
var json_data = JSON.parse(data);
|
16
|
-
|
17
|
-
console.log(json_data);
|
18
|
-
that.new_message(json_data);
|
19
|
-
}
|
20
|
-
}
|
21
|
-
conn.open("GET","/websocket",true);
|
22
|
-
conn.send();
|
23
|
-
|
24
|
-
|
25
|
-
that.trigger = function(event_name, data, client_id) {
|
26
|
-
var payload = JSON.stringify([event_name,data]);
|
27
|
-
$.ajax({
|
28
|
-
type: 'POST',
|
29
|
-
url: '/websocket',
|
30
|
-
data: {client_id: client_id, data: payload},
|
31
|
-
success: function(){console.log('success');}
|
32
|
-
});
|
33
|
-
return this;
|
34
|
-
}
|
35
|
-
|
36
|
-
that.trigger_channel = function(channel, event_name, data, client_id) {
|
37
|
-
var payload = JSON.stringify([channel,event_name,data]);
|
38
|
-
$.ajax({
|
39
|
-
type: 'POST',
|
40
|
-
url: '/websocket',
|
41
|
-
data: {client_id: client_id, data: payload},
|
42
|
-
success: function(){console.log('success');}
|
43
|
-
});
|
44
|
-
return this;
|
45
|
-
}
|
46
|
-
}
|
47
|
-
|
48
|
-
WebSocketRails.XMLHttpFactories = [
|
49
|
-
function () {return new XMLHttpRequest()},
|
50
|
-
function () {return new ActiveXObject("Msxml2.XMLHTTP")},
|
51
|
-
function () {return new ActiveXObject("Msxml3.XMLHTTP")},
|
52
|
-
function () {return new ActiveXObject("Microsoft.XMLHTTP")}
|
53
|
-
];
|
54
|
-
|
55
|
-
WebSocketRails.createXMLHttpObject = function() {
|
56
|
-
var xmlhttp = false,
|
57
|
-
factories = WebSocketRails.XMLHttpFactories;
|
58
|
-
for (var i=0;i<factories.length;i++) {
|
59
|
-
try {
|
60
|
-
xmlhttp = factories[i]();
|
61
|
-
}
|
62
|
-
catch (e) {
|
63
|
-
continue;
|
64
|
-
}
|
65
|
-
break;
|
66
|
-
}
|
67
|
-
return xmlhttp;
|
68
|
-
}
|
@@ -1,38 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* WebSocket Interface for the WebSocketRails client.
|
3
|
-
*/
|
4
|
-
WebSocketRails.WebSocketConnection = function(url,dispatcher){
|
5
|
-
var that = this,
|
6
|
-
conn = new WebSocket("ws://"+url);
|
7
|
-
|
8
|
-
that.trigger = function(event_name, data, client_id) {
|
9
|
-
var payload = JSON.stringify([event_name,data])
|
10
|
-
conn.send( payload )
|
11
|
-
return this;
|
12
|
-
}
|
13
|
-
|
14
|
-
that.trigger_channel = function(channel, event_name, data, client_id) {
|
15
|
-
var payload = JSON.stringify([channel,event_name,data])
|
16
|
-
conn.send( payload )
|
17
|
-
return this;
|
18
|
-
}
|
19
|
-
|
20
|
-
conn.onmessage = function(evt) {
|
21
|
-
var data = JSON.parse(evt.data);
|
22
|
-
|
23
|
-
console.log(data)
|
24
|
-
that.new_message(data);
|
25
|
-
}
|
26
|
-
|
27
|
-
conn.onclose = function(evt) {
|
28
|
-
dispatcher.dispatch('connection_closed', '')
|
29
|
-
}
|
30
|
-
|
31
|
-
var dispatch = function(event_name, message) {
|
32
|
-
var chain = callbacks[event_name]
|
33
|
-
if (typeof chain == 'undefined') return;
|
34
|
-
for(var i = 0; i < chain.length; i++) {
|
35
|
-
chain[i]( message )
|
36
|
-
}
|
37
|
-
}
|
38
|
-
}
|
@@ -1,100 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* WebsocketRails JavaScript Client
|
3
|
-
*
|
4
|
-
* Setting up the dispatcher:
|
5
|
-
* var dispatcher = new WebSocketRails('localhost:3000');
|
6
|
-
* dispatcher.on_open = function() {
|
7
|
-
* // trigger a server event immediately after opening connection
|
8
|
-
* dispatcher.trigger('new_user',{user_name: 'guest'});
|
9
|
-
* })
|
10
|
-
*
|
11
|
-
* Triggering a new event on the server
|
12
|
-
* dispatcher.trigger('event_name',object_to_be_serialized_to_json);
|
13
|
-
*
|
14
|
-
* Listening for new events from the server
|
15
|
-
* dispatcher.bind('event_name', function(data) {
|
16
|
-
* console.log(data.user_name);
|
17
|
-
* })
|
18
|
-
*/
|
19
|
-
var WebSocketRails = function(url) {
|
20
|
-
var that = this,
|
21
|
-
client_id = 0;
|
22
|
-
|
23
|
-
that.state = 'connecting';
|
24
|
-
|
25
|
-
if( typeof(WebSocket) != "function" && typeof(WebSocket) != "object" ) {
|
26
|
-
var conn = new WebSocketRails.HttpConnection(url);
|
27
|
-
} else {
|
28
|
-
var conn = new WebSocketRails.WebSocketConnection(url,that);
|
29
|
-
}
|
30
|
-
|
31
|
-
var on_open = function(data) {
|
32
|
-
that.state = 'connected';
|
33
|
-
that.connection_id = data.connection_id;
|
34
|
-
|
35
|
-
if (typeof that.on_open !== 'undefined') {
|
36
|
-
that.on_open(data);
|
37
|
-
}
|
38
|
-
}
|
39
|
-
|
40
|
-
conn.new_message = function(data) {
|
41
|
-
for(i = 0; i < data.length; i++) {
|
42
|
-
socket_message = data[i];
|
43
|
-
var is_channel = false;
|
44
|
-
|
45
|
-
if (data.length > 2) {
|
46
|
-
var channel_name = socket_message[0],
|
47
|
-
event_name = socket_message[1],
|
48
|
-
message = socket_message[2];
|
49
|
-
is_channel = true;
|
50
|
-
} else {
|
51
|
-
var event_name = socket_message[0],
|
52
|
-
message = socket_message[1];
|
53
|
-
}
|
54
|
-
if (that.state === 'connecting' && event_name === 'client_connected') {
|
55
|
-
on_open(message);
|
56
|
-
}
|
57
|
-
if (is_channel == true) {
|
58
|
-
that.dispatch_channel(channel_name, event_name, message);
|
59
|
-
} else {
|
60
|
-
that.dispatch(event_name, message);
|
61
|
-
}
|
62
|
-
}
|
63
|
-
}
|
64
|
-
|
65
|
-
var callbacks = {};
|
66
|
-
|
67
|
-
that.bind = function(event_name, callback) {
|
68
|
-
callbacks[event_name] = callbacks[event_name] || [];
|
69
|
-
callbacks[event_name].push(callback);
|
70
|
-
}
|
71
|
-
|
72
|
-
that.trigger = function(event_name, data) {
|
73
|
-
conn.trigger(event_name,data,that.connection_id);
|
74
|
-
}
|
75
|
-
|
76
|
-
that.trigger_channel = function(channel, event_name, data) {
|
77
|
-
conn.trigger_channel(channel,event_name,data,that.connection_id);
|
78
|
-
}
|
79
|
-
|
80
|
-
var channels = {};
|
81
|
-
that.subscribe = function(channel_name) {
|
82
|
-
var channel = new WebSocketRails.Channel(channel_name,this);
|
83
|
-
channels[channel_name] = channel;
|
84
|
-
return channel;
|
85
|
-
}
|
86
|
-
|
87
|
-
that.dispatch = function(event_name, message) {
|
88
|
-
var chain = callbacks[event_name];
|
89
|
-
if (typeof chain == 'undefined') return;
|
90
|
-
for(var i = 0; i < chain.length; i++) {
|
91
|
-
chain[i]( message );
|
92
|
-
}
|
93
|
-
}
|
94
|
-
|
95
|
-
that.dispatch_channel = function(channel, event_name, message) {
|
96
|
-
var channel = that.channels[channel];
|
97
|
-
if (typeof channel == 'undefined') return;
|
98
|
-
channel.dispatch(event_name, message);
|
99
|
-
}
|
100
|
-
}
|