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!”)



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/xmpp4r-observable.rb', line 381

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.



374
375
376
# File 'lib/xmpp4r-observable.rb', line 374

def auto
  @auto
end

#jidObject (readonly)

Returns the value of attribute jid.



374
375
376
# File 'lib/xmpp4r-observable.rb', line 374

def jid
  @jid
end

#pubsubObject (readonly)

Returns the value of attribute pubsub.



374
375
376
# File 'lib/xmpp4r-observable.rb', line 374

def pubsub
  @pubsub
end

#subsObject (readonly)

Returns the value of attribute subs.



374
375
376
# File 'lib/xmpp4r-observable.rb', line 374

def subs
  @subs
end

Instance Method Details

#attach_auto_observerObject

Attach an auto-observer based on QObserver

Raises:

  • (StandardError)


430
431
432
433
434
435
436
437
# File 'lib/xmpp4r-observable.rb', line 430

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.



538
539
540
541
# File 'lib/xmpp4r-observable.rb', line 538

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)


525
526
527
528
529
# File 'lib/xmpp4r-observable.rb', line 525

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.



509
510
511
512
513
514
515
516
517
518
519
520
521
# File 'lib/xmpp4r-observable.rb', line 509

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).



595
596
597
# File 'lib/xmpp4r-observable.rb', line 595

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.



589
590
591
# File 'lib/xmpp4r-observable.rb', line 589

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.



465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
# File 'lib/xmpp4r-observable.rb', line 465

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.



581
582
583
584
# File 'lib/xmpp4r-observable.rb', line 581

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)


440
441
442
443
444
445
446
447
# File 'lib/xmpp4r-observable.rb', line 440

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.



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

def disconnect
	disconnect!
end

#inspectObject

:nodoc:



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

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



421
422
423
424
425
426
427
# File 'lib/xmpp4r-observable.rb', line 421

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



412
413
414
415
416
417
418
# File 'lib/xmpp4r-observable.rb', line 412

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.



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

def reconnect
	@disconnected = false
	connect!
end

#rosterObject

Direct access to the underlying Roster helper.



532
533
534
535
# File 'lib/xmpp4r-observable.rb', line 532

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

#send!(msg) ⇒ Object

Send a Jabber stanza over-the-wire.



544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
# File 'lib/xmpp4r-observable.rb', line 544

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! :-)



495
496
497
498
499
500
# File 'lib/xmpp4r-observable.rb', line 495

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