padrino-websockets 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29fa2c66e13018259a69e4c31ae06bd65c6e636b
4
- data.tar.gz: 65df06207d203791552bf15743e380a7236dd110
3
+ metadata.gz: 48a6c2dbc40407de9d89363244273ea101a333b9
4
+ data.tar.gz: f55b458cb97d4931a9bb9178827961e5a3a24819
5
5
  SHA512:
6
- metadata.gz: ad15ee0928289ec7ddb10c7d2f079ef42de8d43ac2935d8855d9e52c0e539d5ce31b4538037892020d1861a4c9c625e6778249211ba7199017c208fdcb5a978c
7
- data.tar.gz: 7846d58a63850da913458687f0d2535d529d83b57ca39a986df9a5ed4325c4cd2549fcdf9d1cdef9080c4d878bd3c3c1ef6d5460741671dabae3ad663e032fa4
6
+ metadata.gz: de5f1cc610fb4b047ca7beea1b5d735fab5eb5fb298085efb96578c45eed5fa7b4673ebf1b8fbb36be3b57b0b310a677960042e32c696d3877cd267c213d1def
7
+ data.tar.gz: b1f972357d3054ebe90b4fa5c727acc90a16d8b59e40ed0500e83591a81e391e6a0f2def90f02279a8ecb15fe3d2ff43c43d77e3c1df35045f62ec7441af6e1e
data/README.md CHANGED
@@ -5,20 +5,25 @@ A WebSockets abstraction for the Padrino Ruby Web Framework to manage
5
5
 
6
6
  ## Current support
7
7
 
8
- The current version supports [SpiderGazelle](https://github.com/cotag/spider-gazelle) as its
9
- backend working with LibUV.
8
+ * [SpiderGazelle](https://github.com/cotag/spider-gazelle) a LibUV application server.
9
+ * [Puma](http://puma.io/) >= 2.0. (*)
10
+ * [Thin](http://code.macournoyer.com/thin/) (*)
11
+ * [Rainbows](http://rainbows.rubyforge.org/) (*) (**)
12
+ * [Goliath](http://postrank-labs.github.com/goliath/) (*) (**)
13
+ * [Phusion Passenger](https://www.phusionpassenger.com/) >= 4.0 with nginx >= 1.4 (*) (**)
14
+
15
+ (*) Supported through [faye-websocket-ruby](https://github.com/faye/faye-websocket-ruby).
16
+ (**) Untested.
17
+
18
+
19
+ UPDATE: See the [faye-support](https://github.com/dariocravero/padrino-websockets/tree/faye-support) branch for Thin support (more updats coming on this).
10
20
 
11
- Feel free to implement your own backend using, say, EventMachine and submit it! :)
12
21
 
13
22
  ## Installation
14
23
 
15
24
  Add this line to your application's `Gemfile`:
16
25
 
17
26
  ```
18
- # It only works with SpiderGazelle for now, so this dependency is a must at the moment.
19
- gem 'spider-gazelle', github: 'cotag/spider-gazelle'
20
- gem 'uv-rays', github: 'cotag/uv-rays'
21
-
22
27
  gem 'padrino-websockets'
23
28
  ```
24
29
 
@@ -46,7 +51,7 @@ Then in any controller or in the app itself, define a WebSocket channel:
46
51
 
47
52
  ```
48
53
  websocket :channel do
49
- event :ping do |context, message|
54
+ on :ping do |message|
50
55
  send_message({pong: true, data: message})
51
56
  end
52
57
  end
@@ -46,6 +46,7 @@ module Padrino
46
46
  def event(name, &block)
47
47
  @events[name.to_sym] = block if block_given?
48
48
  end
49
+ alias :on :event
49
50
 
50
51
  ##
51
52
  # Message receiver
@@ -86,13 +87,12 @@ module Padrino
86
87
  end
87
88
 
88
89
  # Call it
89
- # TODO Run the event in the context of the app
90
- # @events[event].bind(@event_context).call
91
90
  # TODO Make the params (message) available through the params variable as we do
92
91
  # in normal actions.
93
92
  logger.debug "Calling event: #{event} as user: #{@user} on channel #{@channel}."
94
93
  logger.debug message.inspect
95
- @events[event].call(@event_context, message)
94
+ # Run the event in the context of the app
95
+ @event_context.instance_exec message, &@events[event]
96
96
  rescue Oj::ParseError => e
97
97
  logger.error ERRORS[:parse_message]
98
98
  logger.error e.message
@@ -127,20 +127,6 @@ module Padrino
127
127
  @@connections[@channel].delete(@ws)
128
128
  end
129
129
 
130
- ##
131
- # Broadcast a message to the whole channel
132
- #
133
- def broadcast(message, except=[])
134
- self.class.broadcast @channel, message, except
135
- end
136
-
137
- ##
138
- # Send a message to a user on the channel
139
- #
140
- def send_message(message, user=@user)
141
- self.class.send_message @channel, user, message
142
- end
143
-
144
130
  class << self
145
131
  ##
146
132
  # Broadcast a message to the whole channel.
@@ -0,0 +1,45 @@
1
+ module Padrino
2
+ module WebSockets
3
+ module Faye
4
+ class EventManager < BaseEventManager
5
+ def initialize(channel, user, ws, event_context, &block)
6
+ ws.on :open do |event|
7
+ self.on_open event #&method(:on_open)
8
+ end
9
+ ws.on :message do |event|
10
+ self.on_message event.data, @ws
11
+ end
12
+ ws.on :close do |event|
13
+ self.on_shutdown event # method(:on_shutdown)
14
+ end
15
+
16
+ super channel, user, ws, event_context, &block
17
+ end
18
+
19
+ ##
20
+ # Manage the WebSocket's connection being closed.
21
+ #
22
+ def on_shutdown(event)
23
+ @pinger.cancel if @pinger
24
+ end
25
+
26
+ ##
27
+ # Write a message to the WebSocket.
28
+ #
29
+ def self.write(message, ws)
30
+ ws.send ::Oj.dump(message)
31
+ end
32
+
33
+ protected
34
+ ##
35
+ # Maintain the connection if ping frames are supported
36
+ #
37
+ def on_open(event)
38
+ super event
39
+
40
+ @ws.ping('pong')
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ module Padrino
2
+ module WebSockets
3
+ module Faye
4
+ module Helpers
5
+ def send_message(channel, user, message)
6
+ Padrino::WebSockets::Faye::EventManager.send_message channel, user, message
7
+ end
8
+
9
+ def broadcast(channel, message, except=[])
10
+ Padrino::WebSockets::Faye::EventManager.broadcast channel, message, except
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ module Faye
2
+ class RackStream
3
+ def initialize(socket_object)
4
+ @socket_object = socket_object
5
+ @connection = socket_object.env['em.connection']
6
+ @stream_send = socket_object.env['stream.send']
7
+
8
+ if socket_object.env['rack.hijack']
9
+ socket_object.env['rack.hijack'].call
10
+ #
11
+ # FIXME For some reason `rack.hijack_io` isn't set in `Padrino` when using it with `Puma`.
12
+ # In the meantime, if you're using this, you can get away with `puma.socket`
13
+ #
14
+ @rack_hijack_io = socket_object.env['rack.hijack_io'] || socket_object.env['puma.socket']
15
+ EventMachine.attach(@rack_hijack_io, Reader) do |reader|
16
+ @rack_hijack_io_reader = reader
17
+ reader.stream = self
18
+ end
19
+ end
20
+
21
+ @connection.socket_stream = self if @connection.respond_to?(:socket_stream)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ module Padrino
2
+ module WebSockets
3
+ module Faye
4
+ module Routing
5
+ require 'faye/websocket'
6
+
7
+ ##
8
+ # Creates a WebSocket endpoint using SpiderGazelle + libuv.
9
+ #
10
+ # It handles upgrading the HTTP connection for you.
11
+ # You can nest this inside controllers as you would do with regular actions in Padrino.
12
+ #
13
+ def websocket(channel, *args, &block)
14
+ get channel, *args do
15
+ # Let some other action try to handle the request if it's not a WebSocket.
16
+ throw :pass unless ::Faye::WebSocket.websocket?(request.env)
17
+
18
+ set_websocket_user
19
+ ws = ::Faye::WebSocket.new(env, nil, {ping: 15})
20
+ Padrino::WebSockets::Faye::EventManager.new(channel, session['websocket_user'],
21
+ ws, self, &block)
22
+ ws.rack_response
23
+ end
24
+ end
25
+ alias :ws :websocket
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ module Padrino
2
+ module WebSockets
3
+ module Faye
4
+ require 'padrino-websockets/faye/helpers'
5
+ require 'padrino-websockets/faye/routing'
6
+ require 'padrino-websockets/faye/event-manager'
7
+ end
8
+ end
9
+ end
@@ -5,8 +5,9 @@ module Padrino
5
5
  def send_message(channel, user, message)
6
6
  Padrino::WebSockets::SpiderGazelle::EventManager.send_message channel, user, message
7
7
  end
8
- def broadcast(channel, message)
9
- Padrino::WebSockets::SpiderGazelle::EventManager.broadcast channel, message
8
+
9
+ def broadcast(channel, message, except=[])
10
+ Padrino::WebSockets::SpiderGazelle::EventManager.broadcast channel, message, except
10
11
  end
11
12
  end
12
13
  end
@@ -1,5 +1,5 @@
1
1
  module Padrino
2
2
  module Websockets
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -18,8 +18,16 @@ module Padrino
18
18
  require 'padrino-websockets/spider-gazelle'
19
19
  app.helpers Padrino::WebSockets::SpiderGazelle::Helpers
20
20
  app.extend Padrino::WebSockets::SpiderGazelle::Routing
21
+ elsif defined?(::Faye::WebSocket)
22
+ require 'padrino-websockets/faye'
23
+ ::Faye::WebSocket.load_adapter('thin') if defined?(::Thin)
24
+ require 'padrino-websockets/faye/puma-patch' if defined?(Puma)
25
+ app.helpers Padrino::WebSockets::Faye::Helpers
26
+ app.extend Padrino::WebSockets::Faye::Routing
21
27
  else
22
- logger.error "Can't find a WebSockets backend. At the moment we only support SpiderGazelle."
28
+ logger.error %Q{Can't find a WebSockets backend. At the moment we only support
29
+ SpiderGazelle and Faye Websockets friendly application backends (Puma and Thin work,
30
+ Rainbows, Goliath and Phusion Passenger remain untested and may break).}
23
31
  raise NotImplementedError
24
32
  end
25
33
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: padrino-websockets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darío Javier Cravero
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-23 00:00:00.000000000 Z
11
+ date: 2014-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -64,6 +64,11 @@ files:
64
64
  - examples/padrino-app/public/favicon.ico
65
65
  - lib/padrino-websockets.rb
66
66
  - lib/padrino-websockets/base-event-manager.rb
67
+ - lib/padrino-websockets/faye.rb
68
+ - lib/padrino-websockets/faye/event-manager.rb
69
+ - lib/padrino-websockets/faye/helpers.rb
70
+ - lib/padrino-websockets/faye/puma-patch.rb
71
+ - lib/padrino-websockets/faye/routing.rb
67
72
  - lib/padrino-websockets/spider-gazelle.rb
68
73
  - lib/padrino-websockets/spider-gazelle/event-manager.rb
69
74
  - lib/padrino-websockets/spider-gazelle/helpers.rb
@@ -95,3 +100,4 @@ signing_key:
95
100
  specification_version: 4
96
101
  summary: A WebSockets abstraction for Padrino
97
102
  test_files: []
103
+ has_rdoc: