session.rb
来自「用ruby on rails写的一个博客程序,还不错..ruby on rail」· RB 代码 · 共 616 行 · 第 1/2 页
RB
616 行
# License: see LICENSE.txt# Jabber4R - Jabber Instant Messaging Library for Ruby# Copyright (C) 2002 Rich Kilmer <rich@infoether.com># module Jabber HEX = "0123456789abcdef" ## # Generates a random hex string in the following format: # JRR_01234567 # # return:: [String] The resource id # def Jabber.gen_random_resource return Jabber.gen_random_id("JRR_", 8) end ## # Generates a random thread as a hex string in the following format: # JRT_01234567890123456789 # # return:: [String] The thread id # def Jabber.gen_random_thread return Jabber.gen_random_id("JRT_", 20) end ## # Generates a random id as a hex string # # prefix:: [String="Jabber4R_] The prefix for the random hex data # length:: [Integer=16] The number of hex characters # return:: [String] The random id # def Jabber.gen_random_id(prefix="Jabber4R_", length=16) length.times {prefix += HEX[rand(16),1]} prefix end class Subscription attr_accessor :type, :from, :id, :session def initialize(session, type, from, id) @session = session @type = type @from = from @id = id end def accept case type when :subscribe @session.connection.send(Jabber::Protocol::Presence.gen_accept_subscription(@id, @from)) when :unsubscribe @session.connection.send(Jabber::Protocol::Presence.gen_accept_unsubscription(@id, @from)) else raise "Cannot accept a subscription of type #{type.to_s}" end end end ## # This is a base class for subscription handlers class SubscriptionHandler def subscribe(subscription) end def subscribed(subscription) end def unsubscribe(subscription) end def unsubscribed(subscription) end end class AutoSubscriptionHandler < SubscriptionHandler def subscribe(subscription) subscription.accept end def unsubscribe(subscription) subscription.accept end end ## # The Jabber Session is the main class for dealing with a Jabber service. # class Session # The host this session is connected to attr_reader :host # The port (defaults to 5222) that this session is connected to attr_reader :port # The Jabber::Protocol::Connection instance attr_reader :connection # The Jabber::Roster instance attr_reader :roster # The session id sent from the Jabber service upon connection attr_reader :session_id # The Jabber::JID of the current session attr_reader :jid # The username to use for authenticating this session attr_accessor :username # The password to use for authenticating this session attr_accessor :password # The resource id for this session attr_accessor :resource # The iq handlers for this session attr_accessor :iqHandlers ## # Session creation factory that creates a session, logs in, # requests the roster, registers message and presence filters # and announces initial presence. Login is done via plaintext # password authentication. # # jid:: [String | JID] The account information ("account@host/resouce") # password:: [String] The account password # port:: [Integer = 5222] The host port # digest:: [Boolean = false] Use digest authentication? # return:: [Jabber::Session] The new session # def Session.bind(jid, password, port=5222, digest=false) jid = Jabber::JID.new(jid) if jid.kind_of? String session = Session.new(jid.host, port) raise "Authentication failed" unless session.authenticate(jid.node, password, jid.resource, digest) session.request_roster session.register_message_filter session.register_presence_filter session.register_iq_filter session.announce_initial_presence session end ## # Account registration method # def Session.register(jid, password, email="", name="", port=5222) jid = Jabber::JID.new(jid) if jid.kind_of? String session = Session.new(jid.host, port) msg_id = session.id registered = false current = Thread.current session.connection.send(Jabber::Protocol::Iq.gen_registration(session, msg_id, jid.node, password, email, name)) do |element| if element.element_tag=="iq" and element.attr_id==msg_id element.consume_element if element.attr_type=="result" registered = true elsif element.attr_type=="error" registered = false end current.wakeup end end Thread.stop session.release return registered end ## # Session creation factory that creates a session, logs in, # requests the roster, registers message and presence filters # and announces initial presence. Login is done via digest (SHA) # password authentication. # # jid:: [String | JID] The account information ("account@host/resouce") # password:: [String] The account password # port:: [Integer = 5222] The host port # return:: [Jabber::Session] The new session # def Session.bind_digest(jid, password, port=5222) Session.bind(jid, password, port, true) end # Creates a new session connected to the supplied host and port. # The method attempts to build a Jabber::Protocol::Connection # object and send the open_stream XML message. It then blocks # to recieve the coorisponding reply open_stream and sets the # session_id from that xml element. # # host:: [String] The hostname of the Jabber service # port:: [Integer=5222] The port of the Jabber service # raise:: [RuntimeException] If connection fails # def initialize(host, port=5222) @id = 1 @host = host @port = port @roster = Roster.new(self) @messageListeners = Hash.new @iqHandlers=Hash.new @subscriptionHandler = nil @connection = Jabber::Protocol::Connection.new(host, port) @connection.connect unless @connection.is_connected? raise "Session Error: Could not connected to #{host}:#{port}" else @connection.send(Jabber::Protocol.gen_open_stream(host)) do |element| if element.element_tag=="stream:stream" element.consume_element @session_id = element.attr_id end end @connection.on_connection_exception do if @session_failure_block self.release @session_failure_block.call end end Thread.stop end end ## # Set a handler for session exceptions that get caught in # communicating with the Jabber server. # def on_session_failure(&block) @session_failure_block = block end ## # Counter for message IDs # # return:: [String] A unique message id for this session # def id @id = @id + 1 return @id.to_s end ## # Authenticate (logs into) this session with the supplied credentials. # The method blocks waiting for a reply to the login message. Sets the # authenticated attribute based on result. # # username:: [String] The username to use for authentication # password:: [String] The password to use for authentication # resource:: [String] The resource ID for this session # digest:: [Boolean=false] True to use digest authentication (not sending password in the clear) # return:: [Boolean] Whether the authentication succeeded or failed # def authenticate(username, password, resource, digest=false) @username = username @password = password @resource = resource @jid = JID.new("#{username}@#{@host}/#{resource}") @roster.add(@jid, "both", "Me", "My Resources") msg_id = self.id authHandler = Proc.new do |element| if element.element_tag=="iq" and element.attr_id==msg_id element.consume_element if element.attr_type=="result" @authenticated = true elsif element.attr_type=="error" @authenticated = false end end end if digest require 'digest/sha1' authRequest = Jabber::Protocol::Iq.gen_auth_digest(self, msg_id, username, Digest::SHA1.new(@session_id + password).hexdigest, resource) else authRequest = Jabber::Protocol::Iq.gen_auth(self, msg_id, username, password, resource) end @connection.send(authRequest, &authHandler) Thread.stop return @authenticated end ## # Is this an authenticated session? # # return:: [Boolean] True if the session is authenticated # def is_authenticated? return @authenticated end ## # Sends the initial presence message to the Jabber service # def announce_initial_presence @connection.send(Jabber::Protocol::Presence.gen_initial(id)) end ## # Sends an extended away presence message # # status:: [String] The status message # def announce_extended_away(status=nil)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?