Class: XMPP4EM::Client

Inherits:
BaseClient show all
Defined in:
lib/xmpp4em/client.rb

Instance Attribute Summary

Attributes inherited from BaseClient

#connection, #user

Instance Method Summary collapse

Methods inherited from BaseClient

#add_iq_callback, #add_message_callback, #add_presence_callback, #close, #connected?, #on, #on_exception, #receive, #reconnect, #register_stanza, #send

Constructor Details

#initialize(user, pass, logger = nil, opts = {}) ⇒ Client

Returns a new instance of Client.



9
10
11
12
# File 'lib/xmpp4em/client.rb', line 9

def initialize user, pass, logger=nil, opts = {}
  super      
  @opts = { :auto_register => false }.merge(opts)        
end

Instance Method Details

#connect(host = jid.domain, port = 5222) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/xmpp4em/client.rb', line 22

def connect host = jid.domain, port = 5222
  if host=='localhost' || host=='127.0.0.1' || %r{^([0-9]{1,3}.){3}[0-9]{1,3}$}.match(host)
    target_host, target_port= host, port
  else
    target_host, target_port = resolve_host(host)
  end
  EM.connect target_host, target_port, ClientConnection, jid.domain, port do |conn|
    @connection = conn
    conn.client = self
    conn.logger=@logger
  end
end

#jidObject



14
15
16
17
18
19
20
# File 'lib/xmpp4em/client.rb', line 14

def jid
  @jid ||= if @user.kind_of?(Jabber::JID)
    @user
  else
    @user =~ /@/ ? Jabber::JID.new(@user) : Jabber::JID.new(@user, 'localhost')
  end
end

#login(&blk) ⇒ Object



60
61
62
63
# File 'lib/xmpp4em/client.rb', line 60

def  &blk
  Jabber::SASL::new(self, 'PLAIN').auth(@pass)
  @auth_callback = blk if block_given?
end

#receive_stanza(stanza) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/xmpp4em/client.rb', line 78

def receive_stanza(stanza)
  
  case stanza.name
    when 'features'
    unless @authenticated
       do |res|
        # log ['login response', res].inspect
        if res == :failure and @opts[:auto_register]
          register do |res|
            #p ['register response', res]
             unless res == :error
          end
        end
      end
      
    else
      if @connection.stream_features.has_key? 'bind'
        iq = Jabber::Iq.new(:set)
        bind = iq.add REXML::Element.new('bind')
        bind.add_namespace @connection.stream_features['bind']            
        resource = bind.add REXML::Element.new('resource')
        resource.text=jid.resource
        
        send(iq){ |reply|
          if reply.type == :result and jid = reply.first_element('//jid') and jid.text
            # log ['new jid is', jid.text].inspect
            @jid = Jabber::JID.new(jid.text)
          end
        }
      end
      
      if @connection.stream_features.has_key? 'session'
        iq = Jabber::Iq.new(:set)
        session = iq.add REXML::Element.new('session')
        session.add_namespace @connection.stream_features['session']
        
        send(iq){ |reply|
          if reply.type == :result
            on(:login, stanza)
          end
        }
      end
    end
    
    return true
    
    when 'success', 'failure'
    if stanza.name == 'success'
      @authenticated = true
      @connection.reset_parser
      @connection.init
    end
    
    @auth_callback.call(stanza.name.to_sym) if @auth_callback
    return true
  end
  false
end

#register(&blk) ⇒ Object



65
66
67
68
69
70
71
72
# File 'lib/xmpp4em/client.rb', line 65

def register &blk
  reg = Jabber::Iq.new_register(jid.node, @pass)
  reg.to = jid.domain
  
  send(reg){ |reply|
    blk.call( reply.type == :result ? :success : reply.type )
  }
end

#resolve_host(domain) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/xmpp4em/client.rb', line 35

def resolve_host(domain)
  srv = []
  begin        
    Resolv::DNS.open { |dns|
      # If ruby version is too old and SRV is unknown, this will raise a NameError
      # which is catched below
      #debug("RESOLVING:\n_xmpp-client._tcp.#{domain} (SRV)")
      srv = dns.getresources("_xmpp-client._tcp.#{domain}", Resolv::DNS::Resource::IN::SRV)
    }
  rescue NameError
    
  end
  
  unless srv.blank?
    # Sort SRV records: lowest priority first, highest weight first
    srv.sort! { |a,b| (a.priority != b.priority) ? (a.priority <=> b.priority) : (b.weight <=> a.weight) }        
    #debug "USING #{srv.first.target.to_s}"
    return srv.first.target.to_s, srv.first.port
  else
    #debug "USING #{domain}:5222"          
    return domain, 5222
  end
  
end

#send_msg(to, msg) ⇒ Object



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

def send_msg to, msg
  send_safe Jabber::Message::new(to, msg).set_type(:chat)
end