Module: Redisse

Extended by:
Redisse
Included in:
Redisse
Defined in:
lib/redisse.rb,
lib/redisse/server.rb,
lib/redisse/version.rb,
lib/redisse/publisher.rb,
lib/redisse/server/redis.rb,
lib/redisse/server/stats.rb,
lib/redisse/configuration.rb,
lib/redisse/server/responses.rb,
lib/redisse/redirect_endpoint.rb,
lib/redisse/server_sent_events.rb

Overview

A HTTP API to serve Server-Sent Events via a Redis backend.

Defined Under Namespace

Modules: ServerSentEvents Classes: RedirectEndpoint, RedisPublisher, Server, TestEvent, TestPublisher

Constant Summary

VERSION =
"0.4.0"

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Instance Attribute Details

- (Object) default_port

The port on which the server listens.

Defaults to the REDISSE_PORT environment variable and if it is not set, to 8080.



22
23
24
# File 'lib/redisse.rb', line 22

def default_port
  @default_port
end

- (Object) nginx_internal_url

The internal URL hierarchy to redirect to with X-Accel-Redirect.

When this property is set, Redisse will work totally differently. Your Ruby code will not be loaded by the events server itself, but only by the #redirect_endpoint Rack app that you will have to route to in your Rack app (e.g. using map in config.ru) and this endpoint will redirect to this internal URL hierarchy.

Defaults to /redisse.



33
34
35
# File 'lib/redisse.rb', line 33

def nginx_internal_url
  @nginx_internal_url
end

- (Object) redis_server

Gets/Sets the String URL of the Redis server to connect to.

Note that while the Redis pubsub mechanism works outside of the Redis key namespace and ignores the database (the path part of the URL), the database will still be used to store an history of the events sent to support Last-Event-Id.

Defaults to the REDISSE_REDIS environment variable and if it is not set, to redis://localhost:6379/.



16
17
18
# File 'lib/redisse.rb', line 16

def redis_server
  @redis_server
end

Class Method Details

+ (Object) channels(&block)

Define the list of channels to subscribe to.

Calls the given block with a Rack environment, the block is expected to return a list of channels the current user has access to. The list is then coerced using Kernel#Array.

Once the block is defined, other calls will be handled by the block directly, as if the method had been redefined directly. It simply gives a nicer API:

Redisse.channels do |env|
end

vs

def Redisse.channels(env)
end

Examples:

Redisse.channels do |env|
  %w( comment post )
end
# will result in subscriptions to 'comment' and 'post' channels.
Redisse.channels({})
# => ["comment", "post"]

Parameters:

  • block

    The block that lists the channels for the given Rack environment.



33
34
35
36
37
38
39
40
# File 'lib/redisse/configuration.rb', line 33

def self.channels(*, &block)
  if block
    # overwrite method with block
    define_singleton_method :channels, &block
  else
    super
  end
end

Instance Method Details

- (Object) channels(env)

The list of channels to subscribe to.

Once channels has been called, the given block is this method. The block must satisfy this interface:

Parameters:

  • env

    The Rack environment for this request.

Returns:

  • an Array of String naming the channels to subscribe to.

Raises:

  • NotImplementedError unless channels has been called.



74
75
76
# File 'lib/redisse.rb', line 74

def channels(env)
  raise NotImplementedError, "you must call Redisse.channels first"
end

- (Object) middlewares

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

List of middlewares defined with #use.

Used by Goliath to build the server.



127
128
129
# File 'lib/redisse.rb', line 127

def middlewares
  @middlewares ||= []
end

- (Object) plugin(name, *args)

Define a Goliath plugin to run with the server.

See Goliath plugins.



145
146
147
# File 'lib/redisse.rb', line 145

def plugin(name, *args)
  plugins << [name, args]
end

- (Object) publish(channel, message)

Send an event to subscribers, of the given type.

All browsers subscribing to the events server will receive a Server-Sent Event of the chosen type.

Examples:

Redisse.publish(:global, notice: 'This is a server-sent event.')
Redisse.publish(:global, 'Hello, World!')
# on the browser side:
var source = new EventSource(eventsURL);
source.addEventListener('notice', function(e) {
  console.log(e.data) // logs 'This is a server-sent event.'
}, false)
source.addEventListener('message', function(e) {
  console.log(e.data) // logs 'Hello, World!'
}, false)

Parameters:

  • channel

    The channel to publish the message to.

  • type_message

    The type of the event and the content of the message, as a Hash of form { type => message } or simply the message as a String, for the default event type :message.



58
59
60
61
62
# File 'lib/redisse.rb', line 58

def publish(channel, message)
  type, message = Hash(message).first if message.respond_to?(:to_h)
  type ||= :message
  publisher.publish(channel, message, type)
end

- (Object) published

Returns the published events.

Fails unless #test_mode! is set.



119
120
121
122
# File 'lib/redisse.rb', line 119

def published
  fail "Call #{self}.test_mode! first" unless publisher.respond_to?(:published)
  publisher.published
end

- (Object) redirect_endpoint

The Rack application that redirects to #nginx_internal_url.

If you set #nginx_internal_url, you need to call this Rack application to redirect to the Redisse server.

Also note that when using the redirect endpoint, two channel names are reserved, and cannot be used: polling and lastEventId.

Examples:

map "/events" { run Redisse.redirect_endpoint }


160
161
162
# File 'lib/redisse.rb', line 160

def redirect_endpoint
  @redirect_endpoint ||= RedirectEndpoint.new self
end

- (Object) run

Run the server.

If you use the provided binary you don't need to call this method.

By default, the #channels method is called directly.

If #nginx_internal_url is set, the channels will actually come from the internal redirect URL generated in the Rack app by #redirect_endpoint.



17
18
19
20
21
22
23
24
# File 'lib/redisse/server.rb', line 17

def run
  run_as_standalone if nginx_internal_url
  server = Server.new(self)
  runner = Goliath::Runner.new(ARGV, server)
  runner.app = Goliath::Rack::Builder.build(self, server)
  runner.load_plugins([Server::Stats] + plugins)
  runner.run
end

- (Object) test_filter=(filter)

Filter events stored in test mode.

If set, only events whose type match with the filter are stored in #published. A filter matches by using case equality, which allows using a simple Symbol or a Proc for more advanced filters:

Automatically sets #test_mode!, so it also clears the previous events.

Examples:

Redisse.test_filter = -> type { %i(foo baz).include? type }
Redisse.publish :global, foo: 'stored'
Redisse.publish :global, bar: 'skipped'
Redisse.publish :global, baz: 'stored'
Redisse.published.size # => 2


111
112
113
114
# File 'lib/redisse.rb', line 111

def test_filter=(filter)
  test_mode!
  publisher.filter = filter
end

- (Object) test_mode!

Use test mode.

Instead of actually publishing to Redis, events will be stored in #published to use for tests.

Must be called before each test in order for published events to be emptied.

See also #test_filter=.

Examples:

# RSpec
before { Redisse.test_mode! }


92
93
94
# File 'lib/redisse.rb', line 92

def test_mode!
  @publisher = TestPublisher.new
end

- (Object) use(middleware, *args, &block)

Define a middleware for the server.

See Goliath middlewares.

Examples:

Redisse.use MyMiddleware, foo: true


138
139
140
# File 'lib/redisse.rb', line 138

def use(middleware, *args, &block)
  middlewares << [middleware, args, block]
end