📄 protocol.rb
字号:
# def Iq.gen_registration(session, id, username, password, email, name) iq = Iq.new(session, id) iq.type = "set" iq.xmlns = "jabber:iq:register" iq.data = XMLElement.new("username").add_data(username).to_s iq.data << XMLElement.new("password").add_data(password).to_s iq.data << XMLElement.new("email").add_data(email).to_s iq.data << XMLElement.new("name").add_data(name).to_s return iq end ## # Generates an IQ Roster Item add request XML element # # session:: [Session] The session # id:: [String] The message id # jid:: [JID] The Jabber ID to add to the roster # name:: [String] The full name # return:: [String] The XML data to send # def Iq.gen_add_rosteritem(session, id, jid, name) iq = Iq.new(session, id) iq.type = "set" iq.xmlns = "jabber:iq:roster" iq.data = XMLElement.new("item").add_attribute("jid", jid).add_attribute("name", name).to_s return iq end ## # Generates an IQ authortization request XML element # # id:: [String] The message id # username:: [String] The username # password:: [String] The password # resource:: [String] The resource to bind this session to # return:: [String] The XML data to send # def Iq.gen_auth(session, id, username, password, resource) iq = Iq.new(session, id) iq.type = "set" iq.xmlns = "jabber:iq:auth" iq.data = XMLElement.new("username").add_data(username).to_s iq.data << XMLElement.new("password").add_data(password).to_s iq.data << XMLElement.new("resource").add_data(resource).to_s return iq #element = XMLElement.new("iq", {"type"=>"set", "id"=>id}).add_child("query", {"xmlns"=>"jabber:iq:auth"}).add_child("username").add_data(username).to_parent.add_child("password").add_data(password).to_parent.add_child("resource").add_data(resource).to_parent.to_s end ## # Generates an IQ digest authortization request XML element # # id:: [String] The message id # username:: [String] The username # digest:: [String] The SHA-1 hash of the sessionid and the password # resource:: [String] The resource to bind this session to # return:: [String] The XML data to send # def Iq.gen_auth_digest(session, id, username, digest, resource) iq = Iq.new(session, id) iq.type = "set" iq.xmlns = "jabber:iq:auth" iq.data = XMLElement.new("username").add_data(username).to_s iq.data << XMLElement.new("digest").add_data(digest).to_s iq.data << XMLElement.new("resource").add_data(resource).to_s return iq #return XMLElement.new("iq", {"type"=>"set", "id"=>id}).add_child("query", {"xmlns"=>"jabber:iq:auth"}).add_child("username").add_data(username).to_parent.add_child("digest").add_data(digest).to_parent.add_child("resource").add_data(resource).to_parent.to_s end ## # Generates an IQ out of bounds XML element # # to:: [JID] The Jabber ID to send to # url:: [String] The data to send # desc:: [String=""] The description of the data # return:: [String] The XML data to send # def Iq.gen_oob(session, to, url, desc="") iq = Iq.new(session, nil) iq.type = "set" iq.xmlns = "jabber:iq:oob" iq.data = XMLElement.new("url").add_data(url).to_s iq.data << XMLElement.new("desc").add_data(desc).to_s return iq #return XMLElement.new("iq", {"type"=>"set"}).add_child("query", {"xmlns"=>"jabber:iq:oob"}).add_child("url").add_data(url).to_parent.add_child("desc").add_data(data).to_parent.to_s end ## # Generates an VCard request XML element # # id:: [String] The message ID # to:: [JID] The jabber id of the account to get the VCard for # return:: [String] The XML data to send # def Iq.gen_vcard(session, id, to) iq = Iq.new(session, id) iq.xmlns = "vcard-temp" iq.type = "get" iq.to = to return iq #return XMLElement.new("iq", {"type"=>"get", "id"=>id, "to"=>to}).add_child("query", {"xmlns"=>"vcard-temp"}).to_s end ## # Sends the IQ to the Jabber service for delivery # # wait:: [Boolean = false] Wait for reply before return? # &block:: [Block] A block to process the message replies # def send(wait=false, &block) if wait iq = nil blockedThread = Thread.current @session.connection.send(self.to_s, block) do |je| if je.element_tag == "iq" and je.attr_id == @id je.consume_element iq = Iq.from_element(@session, je) blockedThread.wakeup end end Thread.stop rturn iq else @session.connection.send(self.to_s, block) if @session end end ## # Builds a reply to an existing Iq # # return:: [Jabber::Protocol::Iq] The result Iq # def reply iq = Iq.new(@session,@id) iq.to = @from iq.id = @id iq.type = 'result' @is_reply = true return iq end ## # Generates XML that complies with the Jabber protocol for # sending the Iq through the Jabber service. # # return:: [String] The XML string. # def to_xml elem = XMLElement.new("iq", { "type"=>@type}) elem.add_attribute("to" ,@to) if @to elem.add_attribute("id", @id) if @id elem.add_child("query").add_attribute("xmlns",@xmlns).add_data(@data.to_s) if @type=="error" then e=elem.add_child("error"); e.add_attribute("code",@errorcode) if @errorcode e.add_data(@error) if @error end return elem.to_s end ## # see to_xml # def to_s to_xml end end class Message attr_accessor :to, :from, :id, :type, :body, :xhtml, :subject, :thread, :x, :oobData, :errorcode, :error NORMAL = "normal" ERROR="error" CHAT="chat" GROUPCHAT="groupchat" HEADLINE="headline" ## # Factory to build a Message from an XMLElement # # session:: [Jabber::Session] The Jabber session instance # element:: [Jabber::Protocol::ParsedXMLElement] The received XML object # return:: [Jabber::Protocol::Message] The newly created Message object # def Message.from_element(session, element) message = Message.new(element.attr_to) message.from = Jabber::JID.new(element.attr_from) if element.attr_from message.type = element.attr_type message.id = element.attr_id message.thread = element.thread.element_data message.body = element.body.element_data message.xhtml = element.xhtml.element_data message.subject = element.subject.element_data message.oobData = element.x.element_data message.session=session return message end ## # Creates a Message # # to:: [String | Jabber::JID] The jabber id to send this message to (or from) # type:: [Integer=NORMAL] The type of message...Message::(NORMAL, CHAT, GROUPCHAT, HEADLINE) # def initialize(to, type=NORMAL) return unless to to = Jabber::JID.new(to) if to.kind_of? String @to = to if to.kind_of? Jabber::JID @type = type end ## # Chaining method...sets the body of the message # # body:: [String] The message body # return:: [Jabber::Protocol::Message] The current Message object # def set_body(body) @body = body.gsub(/[&]/, '&').gsub(/[<]/, '<').gsub(/[']/, ''') self end ## # Chaining method...sets the subject of the message # # subject:: [String] The message subject # return:: [Jabber::Protocol::Message] The current Message object # def set_subject(subject) @subject = subject.gsub(/[&]/, '&').gsub(/[<]/, '<').gsub(/[']/, ''') self end ## # Chaining method...sets the XHTML body of the message # # body:: [String] The message body # return:: [Jabber::Protocol::Message] The current message object # def set_xhtml(xhtml) @xhtml=xhtml self end ## # Chaining method...sets the thread of the message # # thread:: [String] The message thread id # return:: [Jabber::Protocol::Message] The current Message object # def set_thread(thread) @thread = thread self end ## # Chaining method...sets the OOB data of the message # # data:: [String] The message OOB data # return:: [Jabber::Protocol::Message] The current Message object # def set_outofband(data) @oobData = data self end ## # Chaining method...sets the extended data of the message # # x:: [String] The message x data # return:: [Jabber::Protocol::Message] The current Message object # def set_x(x) @x = x self end ## # Sets an error code to be returned(chaining method) # # code:: [Integer] the jabber error code # reason:: [String] Why the error was reported # return:: [Jabber::Protocol::Message] The current Message object # def set_error(code,reason) @errorcode=code @error=reason @type="error" self end ## # Convenience method for send(true) # # ttl:: [Integer = nil] The time (in seconds) to wait for a reply before assuming nil # &block:: [Block] A block to process the message replies # def request(ttl=nil, &block) send(true, ttl, &block) end ## # Sends the message to the Jabber service for delivery # # wait:: [Boolean = false] Wait for reply before return? # ttl:: [Integer = nil] The time (in seconds) to wait for a reply before assuming nil # &block:: [Block] A block to process the message replies # def send(wait=false, ttl=nil, &block) if wait message = nil blockedThread = Thread.current timer_thread = nil timeout = false unless ttl.nil? timer_thread = Thread.new { sleep ttl timeout = true blockedThread.wakeup } end @session.connection.send(self.to_s, block) do |je| if je.element_tag == "message" and je.thread.element_data == @thread je.consume_element message = Message.from_element(@session, je) blockedThread.wakeup unless timeout unless timer_thread.nil? timer_thread.kill timer_thread = nil end end end Thread.stop return message else @session.connection.send(self.to_s, block) if @session end end ## # Sets the session instance # # session:: [Jabber::Session] The session instance # return:: [Jabber::Protocol::Message] The current Message object # def session=(session) @session = session self end ## # Builds a reply to an existing message by setting: # 1. to = from # 2. id = id # 3. thread = thread # 4. type = type # 5. session = session # # return:: [Jabber::Protocol::Message] The reply message # def reply message = Message.new(nil) message.to = @from message.id = @id message.thread = @thread message.type = @type message.session = @session @is_reply = true return message end ## # Generates XML that complies with the Jabber protocol for # sending the message through the Jabber service. # # return:: [String] The XML string. # def to_xml @thread = Jabber.gen_random_thread if @thread.nil? and (not @is_reply) elem = XMLElement.new("message", {"to"=>@to, "type"=>@type}) elem.add_attribute("id", @id) if @id elem.add_child("thread").add_data(@thread) if @thread elem.add_child("subject").add_data(@subject) if @subject elem.add_child("body").add_data(@body) if @body if @xhtml then t=elem.add_child("xhtml").add_attribute("xmlns","http://www.w3.org/1999/xhtml") t.add_child("body").add_data(@xhtml) end if @type=="error" then e=elem.add_child("error"); e.add_attribute("code",@errorcode) if @errorcode e.add_data(@error) if @error end elem.add_child("x").add_attribute("xmlns", "jabber:x:oob").add_data(@oobData) if @oobData elem.add_xml(@x.to_s) if @x return elem.to_s end ## # see to_xml # def to_s to_xml end end ## # Utility class to create valid XML strings # class XMLElement # The parent XMLElement attr_accessor :parent ## # Construct an XMLElement for the supplied tag and attributes # # tag:: [String] XML tag # attributes:: [Hash = {}] The attribute hash[attribute]=value def initialize(tag, attributes={}) @tag = tag @elements = [] @attributes = attributes @data = "" end ## # Adds an attribute to this element # # attrib:: [String] The attribute name # value:: [String] The attribute value # return:: [Jabber::Protocol::XMLElement] self for chaining # def add_attribute(attrib, value) @attributes[attrib]=value self end ## # Adds data to this element # # data:: [String] The data to add # return:: [Jabber::Protocol::XMLElement] self for chaining # def add_data(data) @data += data.to_s self end ## # Sets the namespace for this tag # # ns:: [String] The namespace # return:: [Jabber::Protocol::XMLElement] self for chaining # def set_namespace(ns) @tag+=":#{ns}"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -