Class: Jabber::Observable

Inherits:
Object
  • Object
show all
Includes:
ObservableThing
Defined in:
lib/xmpp4r-observable.rb

Overview

Jabber::Observable - Creates observable Jabber Clients

Defined Under Namespace

Classes: PubSub, Subscriptions

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ObservableThing

#add_observer, #changed, #changed?, #count_notifications, #count_observers, #delete_observer, #delete_observers, #notify_observers, #pending_notifications?, #wait_notifications

Constructor Details

#initialize(jid, password, status = nil, status_message = "Available", host = nil, port = 5222) ⇒ Observable

Create a new Jabber::Observable client. You will be automatically connected to the Jabber server and your status message will be set to the string passed in as the status_message argument.

jabber = Jabber::Observable.new(“[email protected]”, “password”, “Chat with me - Please!”)



415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
# File 'lib/xmpp4r-observable.rb', line 415

def initialize(jid, password, status = nil, status_message = "Available", host = nil, port=5222)
	# Basic stuff
	@jid = jid
	@password = password
	@host = host
	@port = port
	@disconnected = false

	# Message dealing
	@delivered_messages = 0
	@deferred_messages = Queue.new
	start_deferred_delivery_thread

	# Tell everybody I am here
	status(status, status_message)

	# Subscription Accessor
	@subs = Subscriptions.new(self)

	# PubSub Accessor
	@pubsub = PubSub.new(self)

	# Auto Observer placeholder
	@auto = nil
end

Instance Attribute Details

#autoObject (readonly)

Returns the value of attribute auto.



408
409
410
# File 'lib/xmpp4r-observable.rb', line 408

def auto
  @auto
end

#jidObject (readonly)

Returns the value of attribute jid.



408
409
410
# File 'lib/xmpp4r-observable.rb', line 408

def jid
  @jid
end

#pubsubObject (readonly)

Returns the value of attribute pubsub.



408
409
410
# File 'lib/xmpp4r-observable.rb', line 408

def pubsub
  @pubsub
end

#subsObject (readonly)

Returns the value of attribute subs.



408
409
410
# File 'lib/xmpp4r-observable.rb', line 408

def subs
  @subs
end

Instance Method Details

#attach_auto_observerObject

Attach an auto-observer based on QObserver

Raises:

  • (StandardError)


464
465
466
467
468
469
470
471
# File 'lib/xmpp4r-observable.rb', line 464

def attach_auto_observer
	raise StandardError, "Already attached." if ! @auto.nil?

	@auto = QObserver.new
	[ :message, :presence, :iq, :new_subscription, :subscription_request, :event ].each do |thing|
		self.add_observer(thing, @auto)
	end
end

#clientObject

Direct access to the underlying Jabber client.



572
573
574
575
# File 'lib/xmpp4r-observable.rb', line 572

def client
	connect!() unless connected?
	@client
end

#connected?Boolean

Returns true if the Jabber client is connected to the Jabber server, false otherwise.

Returns:

  • (Boolean)


559
560
561
562
563
# File 'lib/xmpp4r-observable.rb', line 559

def connected?
	@client ||= nil
	connected = @client.respond_to?(:is_connected?) && @client.is_connected?
	return connected
end

#contacts(*contacts, &block) ⇒ Object

If contacts is a single contact, returns a Jabber::Contact object representing that user; if contacts is an array, returns an array of Jabber::Contact objects.

When called with a block, contacts will yield each Jabber::Contact object in turn. This is mainly used internally, but exposed as an utility function.



543
544
545
546
547
548
549
550
551
552
553
554
555
# File 'lib/xmpp4r-observable.rb', line 543

def contacts(*contacts, &block)
	@contacts ||= {}
	contakts = []
	contacts.each do |contact|
		jid = contact.to_s
		unless @contacts[jid]
			@contacts[jid] = contact.respond_to?(:ask_for_authorization!) ? contact : Contact.new(self, contact)
		end
		yield @contacts[jid] if block_given?
		contakts << @contacts[jid]
	end
	contakts.size > 1 ? contakts : contakts.first
end

#deferred_max_waitObject

Get the maximum time to wait for a message to be delivered. Default: 600 seconds (10 minutes).



629
630
631
# File 'lib/xmpp4r-observable.rb', line 629

def deferred_max_wait
	@deferred_max_wait || 600
end

#deferred_max_wait=(seconds) ⇒ Object

Sets the maximum time to wait for a message to be delivered (in seconds). It will be removed of the queue afterwards.



623
624
625
# File 'lib/xmpp4r-observable.rb', line 623

def deferred_max_wait=(seconds)
	@deferred_max_wait = seconds
end

#deliver(jid, message, type = :chat) ⇒ Object

Send a message to jabber user jid.

Valid message types are:

* :normal (default): a normal message.
* :chat: a one-to-one chat message.
* :groupchat: a group-chat message.
* :headline: a "headline" message.
* :error: an error message.

If the recipient is not in your contacts list, the message will be queued for later delivery, and the Contact will be automatically asked for authorization (see Jabber::Observable#add).

message should be a string or a valid Jabber::Message object. In either case, the message recipient will be set to jid.



499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
# File 'lib/xmpp4r-observable.rb', line 499

def deliver(jid, message, type=:chat)
	contacts(jid) do |friend|
		unless @subs.subscribed_to? friend
			@subs.add(friend.jid)
			return deliver_deferred(friend.jid, message, type)
		end
		if message.kind_of?(Jabber::Message)
			msg = message
			msg.to = friend.jid
		else
			msg = Message.new(friend.jid)
			msg.type = type
			msg.body = message
		end
		@delivered_messages += 1
		send!(msg)
	end
end

#deliver_deferred(jid, message, type) ⇒ Object

Queue messages for delivery once a user has accepted our authorization request. Works in conjunction with the deferred delivery thread.

You can use this method if you want to manually add friends and still have the message queued for later delivery.



615
616
617
618
# File 'lib/xmpp4r-observable.rb', line 615

def deliver_deferred(jid, message, type)
	msg = {:to => jid, :message => message, :type => type, :time => Time.now}
	@deferred_messages.enq msg
end

#dettach_auto_observerObject

Dettach the auto-observer

Raises:

  • (StandardError)


474
475
476
477
478
479
480
481
# File 'lib/xmpp4r-observable.rb', line 474

def dettach_auto_observer
	raise StandardError, "Not attached." if @auto.nil?

	[ :message, :presence, :iq, :new_subscription, :subscription_request, :event ].each do |thing|
		self.delete_observer(thing, @auto)
	end
	@auto = nil
end

#disconnectObject

Use this to force the client to disconnect and not automatically reconnect.



606
607
608
# File 'lib/xmpp4r-observable.rb', line 606

def disconnect
	disconnect!
end

#inspectObject

:nodoc:



441
442
443
# File 'lib/xmpp4r-observable.rb', line 441

def inspect # :nodoc:
	sprintf("#<%s:0x%x @jid=%s, @delivered_messages=%d, @deferred_messages=%d, @observer_count=%s, @notification_count=%s, @pubsub=%s>", self.class.name, __id__, @jid, @delivered_messages, @deferred_messages.length, observer_count.inspect, notification_count.inspect, @pubsub.inspect)
end

#notification_countObject

Count the notifications really send for each thing



455
456
457
458
459
460
461
# File 'lib/xmpp4r-observable.rb', line 455

def notification_count
	h = {}
	[ :message, :presence, :iq, :new_subscription, :subscription_request, :event ].each do |thing|
		h[thing] = count_notifications(thing)
	end
	h
end

#observer_countObject

Count the registered observers in each thing



446
447
448
449
450
451
452
# File 'lib/xmpp4r-observable.rb', line 446

def observer_count
	h = {}
	[ :message, :presence, :iq, :new_subscription, :subscription_request, :event ].each do |thing|
		h[thing] = count_observers(thing)
	end
	h
end

#reconnectObject

Use this to force the client to reconnect after a force_disconnect.



599
600
601
602
# File 'lib/xmpp4r-observable.rb', line 599

def reconnect
	@disconnected = false
	connect!
end

#rosterObject

Direct access to the underlying Roster helper.



566
567
568
569
# File 'lib/xmpp4r-observable.rb', line 566

def roster
	return @roster if @roster
	self.roster = Roster::Helper.new(client)
end

#send!(msg) ⇒ Object

Send a Jabber stanza over-the-wire.



578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
# File 'lib/xmpp4r-observable.rb', line 578

def send!(msg)
	attempts = 0
	begin
		attempts += 1
		client.send(msg)
	rescue Errno::EPIPE, IOError => e
		sleep 1
		disconnect
		reconnect
		retry unless attempts > 3
		raise e
	rescue Errno::ECONNRESET => e
		sleep (attempts^2) * 60 + 60
		disconnect
		reconnect
		retry unless attempts > 3
		raise e
	end
end

#status(presence, message) ⇒ Object

Set your presence, with a message.

Available values for presence are:

* nil: online.
* :chat: free for chat.
* :away: away from the computer.
* :dnd: do not disturb.
* :xa: extended away.

It’s not possible to set an offline status - to do that, disconnect! :-)



529
530
531
532
533
534
# File 'lib/xmpp4r-observable.rb', line 529

def status(presence, message)
	@presence = presence
	@status_message = message
	stat_msg = Jabber::Presence.new(@presence, @status_message)
	send!(stat_msg)
end