Class: Roda::Component::Faye::ChannelManager

Inherits:
Object
  • Object
show all
Defined in:
lib/roda/component/faye.rb

Instance Method Summary collapse

Instance Method Details

#get_app(request) ⇒ Object



243
244
245
246
247
248
# File 'lib/roda/component/faye.rb', line 243

def get_app request
  request.env['RODA_COMPONENT_FROM_FAYE'] = true
  a = Class.new(Roda::Component.app.class).new
  a.instance_variable_set(:@_request, request)
  a
end

#incoming(message, r, callback) ⇒ Object



120
121
122
123
124
125
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/roda/component/faye.rb', line 120

def incoming(message, r, callback)
  r.env['RODA_COMPONENT_FROM_FAYE'] = true
  r.env['HTTP_X_RODA_COMPONENT_ON_SERVER'] = true

  app = get_app(r)

  session_id = r.session['session_id']
  public_id  = message['ext'] && message['ext']['public_id']
  private_id = message['ext'] && message['ext'].delete('private_id')
  key        = "#{app.component_opts[:redis_namespace]}users:#{session_id}"

  case message['channel']
  when '/meta/connect'
    callback.call message

    if session_id
      redis.call 'HSET', "#{key}/ids", private_id, public_id
      # puts redis.call 'HGETALL', "#{key}/ids"
    end
  when '/meta/disconnect'
    callback.call message

    redis.call 'DEL', "#{key}/ids"
    channels = redis.call 'GET', "#{key}/channels/#{public_id}"
    channels = channels ? JSON.parse(channels) : []

    channels.each do |channel|
      send_sub_to({
        'channel'      => '/meta/unsubscribe',
        'subscription' => channel,
        'ext'          => message['ext']
      }, public_id, private_id, app, key, r)
    end

    redis.call 'DEL', "#{key}/channels/#{public_id}"
  when '/meta/subscribe', '/meta/unsubscribe'
    if message['subscription'][%r{\A/components/}]
      callback.call message
      send_sub_to message, public_id, private_id, app, key, r
    end
  else
    if data = message['data']
      case data['type']
      when 'event'
        options ||= {}
        options.merge! data['local']

        data['event_type'] == 'call' \
          ? options[:call]    = data['event_method'] \
          : options[:trigger] = data['event_method']

        begin
          message['data']['local'] = app.roda_component(:"#{data['name']}", options)
          message['channel']       = message['channel'].gsub(/outgoing/, 'incoming')
        rescue Exception => e
          #fix: faye extentions are capturing errors for some reason
          ap e.message
          ap e.message.inspect
        end
      end
    end

    callback.call message
  end
end

#outgoing(message, request, callback) ⇒ Object

/components/:id/:comp/:action



231
232
233
234
235
236
237
238
239
240
241
# File 'lib/roda/component/faye.rb', line 231

def outgoing(message, request, callback)
  app = get_app request

  # message[:data] = app.roda_component(:auth, call: :cow) || false

  # ap '====OUTGOING===='
  # ap message
  # ap '================'

  callback.call message
end

#redisObject



116
117
118
# File 'lib/roda/component/faye.rb', line 116

def redis
  @redis ||= Redic.new(Roda::Component.app.component_opts[:redis_uri])
end

#send_sub_to(message, public_id, private_id, app, key, request) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/roda/component/faye.rb', line 186

def send_sub_to message, public_id, private_id, app, key, request
  key = "#{key}/channels/#{public_id}"

  joining = message['channel'] == '/meta/subscribe' ? true : false

  component_name = message['subscription'].split('/').last

  channels = redis.call 'GET', key
  channels = channels ? JSON.parse(channels) : []

  if joining
    channels << message['subscription']
  else
    channels.delete message['subscription']
  end

  if channels.length
    redis.call 'SET', key, channels.to_json
  end

  data = app.roda_component(:"#{component_name}", { trigger: (joining ? :join : :leave), public_id: public_id, private_id: private_id })

  url = "http#{request.env['SERVER_PORT'] == '443' ? 's' : ''}://#{request.env['SERVER_NAME']}:#{request.env['SERVER_PORT']}/faye"
  # client = ::Faye::Client.new(url)
  # client.publish "/components/#{component_name}", type: (joining ? 'join' : 'leave'), public_id: public_id, token: app.component_opts[:token], local: data
  # EM.run {
    http = EM::HttpRequest.new(url).post(
      head: {
       'content-type' => 'application/json'
      },
      body: {
        channel: "/components/#{component_name}",
        data: {
          type: (joining ? 'join' : 'leave'), public_id: public_id, token: app.component_opts[:token], local: data }
        }.to_json
    )
    # http.callback {
    #   ap http.response_header.status
    #   ap http.response_header
    #   ap http.response
    # }
  # }
end