Class: Socky::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/socky/client.rb,
lib/socky/client/version.rb,
lib/socky/client/request.rb

Defined Under Namespace

Classes: ArgumentError, AuthenticationError, ConfigurationError, Error, HTTPError, Request

Constant Summary

VERSION =
'0.5.0'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, secret) ⇒ Client

Create Socky::Client instance for later use. This is usually needed only once per application so it's good idea to put it in global variable

Examples:

$socky_client = Socky::Client.new('http://example.org/http/my_app', 'my_secret')


46
47
48
49
# File 'lib/socky/client.rb', line 46

def initialize(uri, secret)
  @uri = URI.parse(uri)
  @secret = secret
end

Class Attribute Details

.loggerObject



25
26
27
28
29
30
31
# File 'lib/socky/client.rb', line 25

def logger
  @logger ||= begin
    log = Logger.new($stdout)
    log.level = Logger::INFO
    log
  end
end

Instance Attribute Details

#logger=(value) ⇒ Object (writeonly)

Sets the attribute logger



35
36
37
# File 'lib/socky/client.rb', line 35

def logger=(value)
  @logger = value
end

#secretObject (readonly)

Returns the value of attribute secret



34
35
36
# File 'lib/socky/client.rb', line 34

def secret
  @secret
end

#uriObject (readonly)

Returns the value of attribute uri



34
35
36
# File 'lib/socky/client.rb', line 34

def uri
  @uri
end

Instance Method Details

#trigger(event, opts = {}) ⇒ Object

Note:

CAUTION! No exceptions will be raised on failure

Trigger event, catching and logging any errors.



105
106
107
108
109
110
111
# File 'lib/socky/client.rb', line 105

def trigger(event, opts = {})
  trigger!(event, opts)
rescue Socky::Client::Error => e
  Socky::Client.logger.error("#{e.message} (#{e.class})")
  Socky::Client.logger.debug(e.backtrace.join("\n"))
  false
end

#trigger!(event, opts = {}) ⇒ Object

Trigger event

Examples:

begin
  $socky_client.trigger!('an_event', :channel => 'my_channe', :data => {:some => 'data'})
rescue Socky::Client::Error => e
  # Do something on error
end

Options Hash (opts):

  • :channel (String)

    Channel to which event will be sent

  • :data (Object)

    Data for trigger - Objects other than strings will be converted to JSON

Raises:

  • (Socky::Client::Error)

    on invalid Socky Server response - see the error message for more details

  • (Socky::Client::HTTPError)

    on any error raised inside Net::HTTP - the original error is available in the original_error attribute



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/socky/client.rb', line 68

def trigger!(event, opts = {})
  require 'net/http' unless defined?(Net::HTTP)
  require 'net/https' if (ssl? && !defined?(Net::HTTPS))
  
  channel = opts[:channel] || opts['channel']
  data = opts[:data] || opts['data']
  raise ArgumentError, 'no channel provided' unless channel
  
  request = Socky::Client::Request.new(self, event, channel, data)
  
  @http_sync ||= begin
    http = Net::HTTP.new(@uri.host, @uri.port)
    http.use_ssl = true if ssl?
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE if ssl?
    http
  end
  
  begin
    response = @http_sync.post(@uri.path,
      request.body, { 'Content-Type'=> 'application/json' })
  rescue Errno::EINVAL, Errno::ECONNRESET, Errno::ECONNREFUSED,
         Timeout::Error, EOFError,
         Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
         Net::ProtocolError => e
    error = Socky::Client::HTTPError.new("#{e.message} (#{e.class})")
    error.original_error = e
    raise error
  end
  
  return handle_response(response.code.to_i, response.body.chomp)
end

#trigger_async(event, opts = {}, &block) ⇒ EM::DefaultDeferrable

Trigger event asynchronously using EventMachine::HttpRequest

Raises:

  • (LoadError)

    unless em-http-request gem is available

  • (Socky::Client::Error)

    unless the eventmachine reactor is running. You probably want to run your application inside a server such as thin.



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/socky/client.rb', line 126

def trigger_async(event, opts = {}, &block)
  unless defined?(EventMachine) && EventMachine.reactor_running?
    raise Error, "In order to use trigger_async you must be running inside an eventmachine loop"
  end
  require 'em-http' unless defined?(EventMachine::HttpRequest)
  
  channel = opts[:channel] || opts['channel']
  data = opts[:data] || opts['data']
  raise ArgumentError, 'no channel provided' unless channel
  
  request = Socky::Client::Request.new(self, event, channel, data)
  
  deferrable = EM::DefaultDeferrable.new
  
  http = EventMachine::HttpRequest.new(@uri).post({
    :timeout => 5, :body => request.body, :head => {'Content-Type'=> 'application/json'}
  })
  http.callback {
    begin
      handle_response(http.response_header.status, http.response.chomp)
      deferrable.succeed
    rescue => e
      deferrable.fail(e)
    end
  }
  http.errback {
    Socky::Client.logger.debug("Network error connecting to socky server: #{http.inspect}")
    deferrable.fail(Error.new("Network error connecting to socky server"))
  }
  
  deferrable
end