Class: Jabber::Reliable::Listener

Inherits:
Object
  • Object
show all
Defined in:
lib/xmpp4r/reliable.rb

Instance Method Summary collapse

Constructor Details

#initialize(full_jid, password, config, &block) ⇒ Listener

Returns a new instance of Listener



49
50
51
52
53
54
55
# File 'lib/xmpp4r/reliable.rb', line 49

def initialize(full_jid, password, config, &block)
  @on_message_block = block
  @full_jid = full_jid
  @config = config
  @password = password
  @max_retry = config[:max_retry] || 30
end

Instance Method Details

#add_exception_handler(&block) ⇒ Object



100
101
102
# File 'lib/xmpp4r/reliable.rb', line 100

def add_exception_handler(&block)
  @exception_handlers << block
end

#authObject



125
126
127
# File 'lib/xmpp4r/reliable.rb', line 125

def auth
  @connection.auth(@password)
end

#connectObject



121
122
123
# File 'lib/xmpp4r/reliable.rb', line 121

def connect
  @connection.connect        
end

#run_exception_handlers(e, connection, where_failed) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/xmpp4r/reliable.rb', line 88

def run_exception_handlers(e, connection, where_failed)
  @exception_handlers.each do |ex_handler|
    ex_handler.call(e, connection, where_failed)
  end
  if where_failed == :sending
    @message_to_send_on_reconnect = @message_now_sending
  end
  if where_failed != :close && !@connection.is_connected?
    @reconnection_thread.raise(e)
  end
end

#send_message(message) ⇒ Object

TODO: test and fix situation where we get disconnected while sending but then successfully reconnect (and make sure in such cases we resent)



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
# File 'lib/xmpp4r/reliable.rb', line 138

def send_message(message)
  unless @connection
    raise ::ArgumentError, "Can't send messages while listener is stopped.  Plase 'start' the listener first."
  end
  retry_count = 0
  begin
    while(not @connection.is_connected?)
      #wait
      Thread.pass
    end
    @message_now_sending = message
    @connection.send(message)
    return true #true, message was sent
  rescue => e
    if e.is_a?(Interrupt)
      raise e
    end
    if(retry_count > @max_retry.to_i)
      Jabber::debuglog "reached max retry count on message re-send, failing"
      raise e
    end
    retry_count += 1
    Jabber::debuglog "retrying message send.." + e.inspect
    retry
  end
end

#send_presenceObject



129
130
131
132
133
134
# File 'lib/xmpp4r/reliable.rb', line 129

def send_presence
  presence_message = @config[:presence_message]
  if presence_message && !presence_message.empty?
    @connection.send(Jabber::Presence.new.set_show(:chat).set_status(presence_message))
  end
end

#setup_connectionObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/xmpp4r/reliable.rb', line 57

def setup_connection
  @connection = Connection.new(@full_jid, @config)
  if @on_message_block
    @connection.add_message_callback(&@on_message_block)
  else
    @connection.add_message_callback do |msg|
      self.on_message(msg)
    end
  end
  
  #We could just reconnect in @connection.on_exception, 
  #but by raising into this seperate thread, we avoid growing our stack trace
  @reconnection_thread = Thread.new do
    first_run = true
    begin
      self.start unless first_run
      loop do 
        sleep(1)
        Thread.pass
      end
    rescue => e
      first_run = false
      retry
    end
  end
  @exception_handlers = []
  @connection.on_exception do |e, connection, where_failed|
    self.run_exception_handlers(e, connection, where_failed)
  end
end

#startObject



104
105
106
107
108
109
110
111
112
113
# File 'lib/xmpp4r/reliable.rb', line 104

def start
  setup_connection unless @connection
  connect
  auth
  send_presence
  if @message_to_send_on_reconnect
    send_message(@message_to_send_on_reconnect)
  end
  @message_to_send_on_reconnect = nil
end

#stopObject

Stop the listener. (close the connection)



116
117
118
119
# File 'lib/xmpp4r/reliable.rb', line 116

def stop
  @connection.close if @connection and @connection.is_connected?
  @connection = nil
end