request_url_withoutHTTP=,canonical_url_withHTTP=,canonical_url_withoutHTTP=,request_url_withoutHTTP_realspaces=. Echtzeitkommunikation (Seite 1 von 1) « Tags « Blog « Bernhard Häussner
Bernhard Häussner
Tags: Artikel mit dem Tag «Echtzeitkommunikation» durchstöbern

XMPP (Jabber) mit Ruby am Beispiel FelicianXMPPBot

15.12.2009, 21:53
FelicianXMPPBot in action

FelicianXMPPBot in action

Das Protokoll XMPP für den (Nahezu-)Echtzeitaustausch von XML-Nachrichten (meist verwendet für IM, als „Jabber“) steht in Konkurrenz und Verbindung mit einigen aktuell mehr oder weniger neuen Technologien, die mit XML und realtime zu tun haben, wie RSS/Atom pings, realtime web oder AJAX. Und ein paar Spielereien auf diesem Gebiet können sicher nicht schaden, also habe ich mit XMPP etwas herumgebastelt.

Weil dies mit PHP irgendwie seltsam wäre und David Strohmayers Text und Präsentation über XMPP mit Java noch nicht existierte, habe ich das ganze mit Ruby gebastelt, da gibt es nämlich den Gem xmpp4r, der mit vielen Beispielen kommt. So konnte ich mal ein bisschem mit Ruby herumspielen. (Zwei Fliegen mit einer Klappe usw.)

Aus den Experimenten ist ein kleiner Server geworden, der einen Jabber-Bot betreibt und über ein einfaches TCP-Protokoll erreicht werden kann, sodass aus allen TCP-Fähigen Skripten (bash mit netcat, PHP…) einfach Nachrichten an einen Jabber-Endpunkt versendet werden können.

Code und Funktionalität bestehen aus drei Teilen:

Die Klasse Netx kümmert sich um den TCP-Server und parst das einfache Protokoll: Man schickt Zeilen und beendet einzelne Nachrichten mit einem Punkt, und die Verbindung (und damit auch die aktuelle Nachricht) mit zwei Punkten. So lassen sich die TCP-Clients leicht implementieren.

Die Klasse XmppRoute bietet nur ein wenig Grundfunktion für den Jabber-Bot. Sie vereinfacht Verbinden und Senden noch weiter, zudem extrahiert sie beim Empfang einer Nachricht einen Befehlsteil.

Der Rest kümmert sich um die Verbindung der beiden Komponenten und um das Parsen von Startup-Parametern.

Aber genug der vielen Worte, jetzt folgt der Code:

jabot.rb

#!/usr/bin/ruby

# Felician 0.9 - XMPP Wrapper
# (c) 2009 by Bernhard Häussner
# Licence: GPLv2+ http://www.gnu.org/licenses/gpl-2.0.txt
#
# This jabber wrapper will recieve messages via simple tcp.
#
# Quit by sending "exit" via jabber. 
# Send "info" via jabber to get running parameters. 
# Send "feedback [msg]" via jabber to post from jabber. 
# Connect to specified port and send messages terminated by lone "." in a line to post via TCP. 
# Send a line with ".." to quit connection. 
#
# Based on xmpp4r-0.5/data/doc/xmpp4r/examples/basic
#

require 'optparse'
require 'XmppRoute'
require 'Netx'

class FelicianXMPPBot
  def start(his_JID,my_txt_JID,my_password,listen_port)
    puts "FELC: Started. Sending to #{his_JID} from #{my_txt_JID} listening to #{listen_port}."
    my_JID=JID.new(my_txt_JID)
    netx=Netx.new
    XmppRoute.connect(my_JID,my_password) do
      on_recieve do |from,cmd,param|
        if from.strip.to_s.eql?his_JID then
          case cmd.downcase
            when 'exit' then
              send(from,"-> I've got to go!")
              puts "FELC: Got shutdown signal, waiting for children to terminate..."
              netx.halt
            when 'feedback' then send(from,param)
            when 'info'then send(from,"-> Felician sending to #{his_JID} listening to #{listen_port}. ")
            else send(from,"-> I don't know: #{cmd} #{param}")
          end
        else
          puts "XMPP: Ignored a message. "
          send(from,"Hi, #{from.strip.to_s}. Sorry, could not be deliverd. Try again later! ")
        end
      end
      
      netx.on_sended do |msg|
        send(his_JID,msg.strip)
        puts "XMPP: Client message sent. "
      end
      netx.listen(listen_port)
    end
    puts "FELC: Shutting down. "
  end
end

if $0 == __FILE__
  #defaults:
  listen_port=2000
  his_JID = "bot_admin@gmx.de"
  my_txt_JID = "i_am_a_bot@jabber.ccc.de/felician"
  my_password = "top_secret"
  # cli settings
  OptionParser.new do |opts|
  opts.banner = 'Usage: ruby jabot.rb -j jid/ressource -p password -t reciever_jid -l port'
  opts.separator ''
  opts.on('-j', '--jid JID', 'sets the sender jid') { |j| my_txt_JID = j }
  opts.on('-p', '--password PASSWORD', 'sets the sender password') { |p| my_password = p }
  opts.on('-t', '--to-jid JID', 'sets the message reciever') { |t| his_JID = t }
  opts.on('-l', '--listen PORT', 'sets the server listen port') { |l| listen_port = l }
    opts.on_tail('-h', '--help', 'Show this message') {
    puts opts
    exit
  }
  opts.parse!(ARGV)
  end
  FelicianXMPPBot.new.start(his_JID,my_txt_JID,my_password,listen_port)
end

XmppRoute.rb

require 'rubygems'
require 'xmpp4r/client'
include Jabber

class XmppRoute
  def initialize(jid,pwd)
    @cmd=Proc.new { |a,b,c| puts "XMPP: No reciever. " }
    @cl = Client.new(jid)
    @cl.connect
    @cl.auth(pwd)
    @cl.send(Presence.new)
    puts "XMPP: Connected! send messages to #{jid.strip.to_s}."
    @cl.add_message_callback { |m| process m }
  end
  def close
    @cl.close
  end
  def on_recieve(&cb)
    @cmd=cb
  end
  def send(to,mes)
    ms = Message.new(to,mes) # [_CY4_L8-R_4LLY-G4T3-R_]
    ms.type = :chat
    @cl.send(ms)
  end
  private
  def process(m)
    puts "XMPP: Got msg of type #{m.type} / #{m.name} with -#{m.body}- "
    if m.type == :chat && ! m.body.nil?
      index=(m.body.index(" ") || 0)-1
      com=m.body[0..index]
      param=(index==-1?"":m.body[index+2..-1])
      puts "XMPP: Call #{com} with --#{param}-- (caused from #{m.from})"
      @cmd.call(m.from,com,param)
    end
  end
  def self.connect(jid,pwd,&block)
    bot=XmppRoute.new(jid,pwd)
    bot.instance_eval(&block)
    bot.close
  end
end

Netx.rb

require 'socket' # Get sockets from stdlib

class Netx
  def initialize; @run=true; end
  def listen(port)
    puts "NETX: Bind to Port #{port}"
    #server = TCPServer.open(port)
    #only local:
    server = TCPServer.open("127.0.0.1",port) # Socket to listen
    while @run
      # this timeout allows us to kill this lop every few seconds...
      begin
        session = Timeout::timeout(10) { server.accept }
        Thread.start(session) { |c| connection c }
      rescue TimeoutError
        #puts "NETX: Refreshing TCPServer."
      end
    end
  end
  def on_sended(&cb); @client_cb=cb; end
  def halt; @run=false; end
  private
  def connection (client)
    puts "NETX: Client conntected..."
    client.puts("-- Hello on Felician at #{Time.now.ctime}. ") # Send the helo & time to the client
    conn_open=true;
    msg_buffer="";
    while conn_open do
      l = client.gets
      if (l.strip.eql?'..') || (l.strip.eql?'.') then
        puts "NETX: Client issued a message..."
        client.puts("-- accepted. ")
        @client_cb.call(msg_buffer)
        msg_buffer="";
        conn_open=false if l.strip.eql?'..'
      else
        msg_buffer << l
      end
    end
  ensure
    client.puts "-- Closing the connection. Bye!"
    puts "NETX: Client disconnect. "
    client.close # Disconnect from the client
  end
end

Erwartet nicht zu viel von dem Code, ist schließlich mein erster Ruby-Code, abgesehen von einigen Hello-World-Sachen. Funktioniert dafür allerdings erstaunlich gut und könnte sich schon fast eigenen, um z.B. einen Systemadministrator über wichtige Aktivitäten und Warnungen aus den verschiedensten Programmen und Wartungsscripten schnell zu informieren.

Man beachte vielleicht noch das alles in dem Code, was in anderen Programmiersprachen als schlechter Stil gälte, hier eher „the ruby way“ ist ;).

Benutzung

Eine Nachricht von der Shell schicken:

09:15  burny@home:~> echo -e "Hallo Welt\n.." | netcat localhost 2000
-- Hello on Felician at Tue Dec 15 21:16:02 2009.
-- accepted.
-- Closing the connection. Bye!

Mal sehen, ob ich das Ganze noch weiter entwickle, meistens ist doch das Senden einer ganz normalen eMail einfacher.

Kommentare: 2 Einträge

Twitter - What am I doing?

27.09.2009, 16:13

Everyone is writing about twitter now. Everyone is thinking he's missing things going on at twitter. Newspapers report about eyewitnesses tweeting things. Twitters user count and press representation is was rapidly growing. So what's it all about? Essentially, it's about a microblogging service that started in 2006 as a small project of Biz Stone and Evan Williams, who wanted their colleagues to answer the simple question "What are you doing?".

I have been a member of Twitter since March 17, 2007 and have tweeted 439 times since then until now (actually not too many updates). Anyway, I noticed a change in how people use twitter. This usage history resulted in a rich variety of uses of twitter. Here are some behaviours I collected over the years:

The What-are-you-doing-guys

There are some users that nearly only answer THE question when it comes to twitter. You are likely to find mostly tweets like "@having breakfast" or "preparing lunch" in their profiles.

It's really funny to follow one of those What-Are-You-Doing-Guys and then meet them. You won't have anything to say, because you do already know (nearly) everything about your fellow tweople.

Also you do really have a log about all the small things you did in life. This might be very interesting some years later.

The Chatroommates

These tweople that only use twitter like a chat are a bit incompatible to the others. They have evolved in the SMS times, when twitter was THE way to text your friends. You might find many senseless tweets like "ok pals I'm off" or "@yomama sure".

The 140-Excited

Some people seem to not want to tell everyone what they are doing and don't have too many friends on twitter, so they don't really have to use twitter. But everyone does, so do they. This is why they seem to focus on (bad?) jokes, proverbs and short quotes.

The Newsfeedorz

When you have found a stream with only headlines and links or 6 of 7 tweets starting like "new blog post:" you know you have found a Newsfeedor. They use twitter only for posting "news". There are famous ones like CNN and rather not too famous ones. And of course many advertisers have found a new channel at twitter. The very bad thing about them: It's usually not original content and it's most of the times better available through RSS.

The Readers

This group is a bit underrepresented. Some of them don't even have a twitter account. They are reading through someones profile (subscribing their stream as RSS) or using one of the services that aggregates twitter messages, like delicious.com. Or they use twitter as a real-time opinion-of-the-tweeting-world search engine. I think the twitter makers had a good reason to change their homepage to a mere search page.

The Retweeters and Answerers

A phenomenon at twitter is retweeting. If you want to pull the attention of your readers to a statement of someone else you retweet that (you just tweet it again putting RT @name in front of it). Or you tell everyone your opinion about it (like: opinion (via @name)) or as direct answer (@name blaaa). Now some tweople only do this. If you look through their stream you will find dozens of answers and you don't get what it's all about. This is a true Retweeter/Answerer.

The Trendy

This is by definition a very popular behaviour: Commenting on the trending topics on twitter. Some "answers" are really funny - and of course it's a cool way to share personal experiences. It's a kind of very fast global FB. Just don't overdo it. (And don't just write "#iamsinglebecause it's trendy". )

So what's correct?

As always - nothing. So what do I do? Simple: Mix. I retweet what I like or want others to know, I answer questions, I keep a log of some things I did, I stay informed about my friends, and I post stuff I put into the cloud.

You can always find new scenarios where you can use a 140-char-messages-posting-page. For example I have started to collect new/strange/biased/funny (German) words. And sometimes I post cryptic messages. For example this one related to the sense of life, a movie, Alice in Wonderland and the time I arrived at school that day.

And because it's always 140-character limited you can display your twitter status e.g. on your website. I do that through my lifestream. My homeserver that serves as a very neat clock too also shows my twitter status to my family.

Kommentare: keine

SchülerVZ Buschfunk verstecken Firefox Add-On

07.05.2009, 18:28

Vor kurzem hat Schülerverzeichnis eine neue „Funktion“ namens „Buschfunk“ auf die Startseite hinzugefügt, die irgendwie jeden zu nerven scheint, mich eingeschlossen. Wozu gibt es Twitter. Deshalb von mir ein Firefox-Add-On um den Buschfunk zu verstecken.

Bisher ist das Add-On noch im Sandkasten, aber falls es sich bewährt (und kompatibel mit den ganzen Mozilla-Richtlinien ist) wird es vielleicht offiziell...

Technisches

Eigentlich ist das Add-On nur ein Greasemonkey-Script, dass mit dem User Script Compiler in ein Add-On umgewandelt wurde. Für alle, die sowieso die Greasemonkey-Erweiterung installiert haben, recht es auch das User-Script zu installieren:

Viel Spaß mit der Erweiterung. Oder viel Spaß ohne Buschfunk und vielleicht mit Twitter.

Edit:

Das Add-On ist obsolet, da es inzwischen das Feature schon auf der Seite gibt.

Kommentare: 4 Einträge

Kopete Kryptographie-Modul und Jabber

20.02.2009, 10:36

Wenn Google durch die Straße fährt und den Vorgarten fotografiert, merkt plötzlich jeder, was Privatsphäre eigentlich ist und warum man sie behalten will. Jedoch scheinen Benutzer von IM-Diensten keine Privatspäre zu mögen. Schleißlich könnten die intimen Chats mit der Freundin jederzeit im Internet oder in einem Buch veröffentlich werden, zumindest wenn diese z.B. über ICQ geschehen, nach akzeptiren vorallem des siebten Absatzes der ICQ Nutzungsbedingungen, der eigentlich schon eine rechte Frechheit darstellt. Doch es geht auch anders:

Zum Beispiel mit den offenen Standards von Jabber/XMPP, die im Gegensatz zu den proprietären Netzwerken wie ICQ über eigene Server laufen können und nicht an eine zentrale Stelle gebunden sind. Außerdem gibt es keine räuberischen Richtlinein zu akzeptieren. Diverse Mail-Provider haben eigene Jabber-Server auf denen man schon einen Account hat, wenn man ein Mailpostfach hat, man muss sich also nichtmal „bei Jabber“ (eben nicht, man braucht nur bei einem Server einen Zugang) anmelden.

Dennoch könnte natürlich jemand (am selben WLAN-Hotspot, am Server, zwischen den Servern etc.) unerlaubt und unbemerkt mithören und damit die Privatsphäre wiederum angreifen. Im Extremfall sogar eigene Nachrichten untermischen. Dagegen kann man sich wiederum durch eine geeignete Ende-zu-Ende-Verschlüsselung schützen. Besonders leicht geht das mit GPG und Kopete.

Da man GPG ja zum Schreiben von E-Mails verwendet, hat man mit entsprechend brisanten Kontaktpersonen meistens onehin schon Schlüssel ausgetauscht und diese signiert. Wer noch nie GPG benutzt hat, kann das z.B. hier lernen. Ist GPG eingerichtet und die Schlüssel getauscht, sind die weiteren Schritte eigentlich recht einfach.

Nachdem man in Kopete das Kryptographie-Modul aktiviert hat und den eigenen Schlüssel ausgewählt hat (damit man die eigenen Nachrichten auch lesen kann) muss man noch den Kontakten, denen man verschlüsselt schreiben will ihre öffentlichen Schlüssel zuweisen (über das Kontextmenü). Vorausgesetzt dies geschieht nicht sowieso schon durch die Adressbuchzuweisungen. Bei den anderen Teilnehmern der Konversation müssen diese Schritte natürlich auch durchgeführt werden, sonst werden die Nachrichten nicht wieder automatisch entschlüsselt oder nur in eine Richtung verschlüsselt.

Kommentare: 2 Einträge
[ Seite 1 ]
 
Χρόνογραφ
© 2008-2017 by Bernhard Häussner - Impressum - Login
Kurz-Link zur Homepage: http://1.co.de/