Module: Plezi::Base::MessageDispatch

Defined in:
lib/plezi/websockets/redis.rb,
lib/plezi/websockets/message_dispatch.rb

Defined Under Namespace

Modules: RedisDriver

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.driversObject (readonly)

Allows pub/sub drivers to attach to the message dispatch using `MessageDispatch.drivers << driver`


9
10
11
# File 'lib/plezi/websockets/message_dispatch.rb', line 9

def drivers
  @drivers
end

Class Method Details

.<<(msg) ⇒ Object


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/plezi/websockets/message_dispatch.rb', line 31

def <<(msg)
  @safe_types ||= [Symbol, Date, Time, Encoding, Struct, Regexp, Range, Set].freeze
  msg = YAML.safe_load(msg, @safe_types)
  return if msg[:origin] == pid
  msg[:type] ||= msg['type'.freeze]
  msg[:type] = Object.const_get msg[:type] if msg[:type] && msg[:type] != :all
  if msg[:target] ||= msg['target'.freeze]
    Iodine::Websocket.defer(target2uuid(msg[:target])) { |ws| ws._pl_ad_review(ws.__send__(ws._pl_ws_map[msg[:event]], *(msg[:args] ||= msg['args'.freeze] || []))) if ws._pl_ws_map[msg[:event] ||= msg['event'.freeze]] }
  elsif (msg[:type]) == :all
    Iodine::Websocket.each { |ws| ws._pl_ad_review(ws.__send__(ws._pl_ws_map[msg[:event]], *(msg[:args] ||= msg['args'.freeze] || []))) if ws._pl_ws_map[msg[:event] ||= msg['event'.freeze]] }
  else
    Iodine::Websocket.each { |ws| ws._pl_ad_review(ws.__send__(ws._pl_ws_map[msg[:event]], *(msg[:args] ||= msg['args'.freeze] || []))) if ws.is_a?(msg[:type]) && msg[:type]._pl_ws_map[msg[:event] ||= msg['event'.freeze]] }
  end

rescue => e
  puts '*** The following could be a security breach attempt:', e.message, e.backtrace
  nil
end

._initObject


19
20
21
# File 'lib/plezi/websockets/message_dispatch.rb', line 19

def _init
  @drivers.each(&:connect)
end

.broadcast(sender, meth, args) ⇒ Object


59
60
61
62
63
64
65
66
67
# File 'lib/plezi/websockets/message_dispatch.rb', line 59

def broadcast(sender, meth, args)
  if sender.is_a?(Class)
    Iodine::Websocket.each { |ws| ws._pl_ad_review(ws.__send__(ws._pl_ws_map[meth], *args)) if ws.is_a?(sender) && ws._pl_ws_map[meth] }
    push type: sender.name, args: args, event: meth
  else
    sender.each { |ws| ws._pl_ad_review(ws.__send__(ws._pl_ws_map[meth], *args)) if ws.is_a?(sender.class) && ws._pl_ws_map[meth] }
    push type: sender.class.name, args: args, event: meth
  end
end

.multicast(sender, meth, args) ⇒ Object


69
70
71
72
73
74
75
76
77
# File 'lib/plezi/websockets/message_dispatch.rb', line 69

def multicast(sender, meth, args)
  if sender.is_a?(Class)
    Iodine::Websocket.each { |ws| ws._pl_ad_review(ws.__send__(ws._pl_ws_map[meth], *args)) if ws._pl_ws_map[meth] }
    push type: :all, args: args, event: meth
  else
    sender.each { |ws| ws._pl_ad_review(ws.__send__(ws._pl_ws_map[meth], *args)) if ws._pl_ws_map[meth] }
    push type: :all, args: args, event: meth
  end
end

.pidObject


15
16
17
# File 'lib/plezi/websockets/message_dispatch.rb', line 15

def pid
  @pid ||= SecureRandom.urlsafe_base64.tap { |str| @prefix_len = str.length }
end

.push(message) ⇒ Object


23
24
25
26
27
28
29
# File 'lib/plezi/websockets/message_dispatch.rb', line 23

def push(message)
  # message[:type] = message[:type].name if message[:type].is_a?(Class)
  message[:origin] = pid
  hst = message.delete(:host) || Plezi.app_name
  yml = message.to_yaml
  @drivers.each { |d| d.push(hst, yml) }
end

.target2pid(target) ⇒ Object


84
85
86
# File 'lib/plezi/websockets/message_dispatch.rb', line 84

def target2pid(target)
  target ? target[0..(@prefix_len - 1)] : Plezi.app_name
end

.target2uuid(target) ⇒ Object


79
80
81
82
# File 'lib/plezi/websockets/message_dispatch.rb', line 79

def target2uuid(target)
  return nil unless target.start_with? pid
  target[@prefix_len..-1].to_i
end

.unicast(_sender, target, meth, args) ⇒ Object


50
51
52
53
54
55
56
57
# File 'lib/plezi/websockets/message_dispatch.rb', line 50

def unicast(_sender, target, meth, args)
  return false if target.nil?
  if (tuuid = target2uuid)
    Iodine::Websocket.defer(tuuid) { |ws| ws._pl_ad_review(ws.__send__(ws._pl_ws_map[meth], *args)) if ws._pl_ws_map[meth] }
    return true
  end
  push target: target, args: args, host: target2pid(target)
end