Post on 17-May-2015
transcript
Microblogging with XMPPReal Time Web
Who am I?
• Name: Stoyan Zhekov
• Private: married, 3 kids (boys)
• Work: Software Engineer
• Contact: xmpp: //zh@jabber.jp
Today
• XMPP (Jabber)
• Microblogging
• Microblogging with XMPP
• My program - xmpp4r, ramaze, sequel
• Questions
Why?
• Web 3.0 ? - Real Time Web?
• RSS is not enough (SUP)
• XMPP (Jabber)
• Webhooks
XMPP (Jabber)
London-Calcutta, message + reply(Peter Saint-Andre)
• 1800: 2 years (ship)
• 1914: 1 month (steamship)
• 1950: 1 week (airmail)
• 1980: 2 days (overnight mail)
• 1994: 10 min (email)
• 1999: 1 sec (IM)
XMPP (history)
• 1998: Jeremie Miller - ICQ - AIM (perl)
• 1999: First rellease
• 2001: Jabber Software Fondation
• 2004: XMPP RFCs (IETF)
What is XMPP?
• JID: node@server/Resource
• Open Protocol
• Decentralized - no central server
• RFC 3290 (core), 3291 (messaging)
• XMPP extension protocols (XEP)
What is XMPP? (2)
• Bidirectional, streaming XML
• One first level tag: <stream>
• 3 second level tags:
• <presence> - presence, subscribtion
• <message> - asynchronous
• <iq> - synchronous
XMPP Features
• Build-in presence
• One-to-one IM (u2u, a2u, a2a)
• Groupchat
• Geolocation
• Security - SSL, TLS
Not only for geeks
• 50 000+ servers, 50+ million users
• Wall Street
• US Department of Defense
• Cisco, Google, Apple
• NTT ?
You on XMPP
• Free account - jabber.jp etc.
• GTalk for domains
• Install your own server:
• ejabberd (erlang) - production
• openfire (java) - easy to install / use
Libraries
• For a lot of OSes and languages
• loudmouth (C)
• xiff (flash)
• smack (java)
• xmpp4r (ruby)
Microblogging
Microblogging
• Web 2.0
• What is it?
• Status changes
• Short notes (140 limit)
• Media files
Big players
• Jaiku
• identi.ca (laconi.ca) - OSS
• Tumblr - http://tt.zhekov.net/
• FriendFeed, Lifestream.fm
Almost Real Time
• XMPP bots (Jaiku, Identi.ca, FriendFeed)
• GNIP - http://www.gnipcentral.com/
• RSS-to-XMPP
• http://notify.me/
• http://notifixio.us/ (WP plugin)
Microblogging with XMPP
• Web 3.0 (Real Time Web)
• PubSub - XEP-0060
• BOSH - XEP-0124
• XEP-XXXX
• ....
Too complicated :(
Am I stupid...? :(
My own program
Design
• XMPP bot
• Simple API
• Simple web frontend
• Models: juick.com , kwippy.com
Components
• models.rb - connection to the DB
• bot.rb - XMPP
• api.rb - service, scaling
• web.rb - browser view
Models
• “Things”
• User
• Micro
• “Relations”
• Subscribe - User-to-User
• Subscribe - User-to-Micro
• Like - User-to-Micro
Relations (Sequel)
class User < Sequel::Model(:users)
one_to_many :micros do |ds| ds.filter(:parent_id => nil) end
one_to_many :subs, :extend => UserFindOrCreate many_to_many :publishers, :class => :User, :join_table => :subs
end
Ruby XMPP Libraries
• xmpp4r - Roster, vCard etc.
• xmpp4r-simple - easy to use
• jabber4r - Thread based :(
XMPP Bot
• http://tr.im/emxmpp (nutrun.com)
• EventMachine - libevent, Deferrable
• Plugins - http://tr.im/modular
ConcurrencyEM.run do EM::PeriodicTimer.new(1) do ... EM.spawn do worker = Worker.new worker.callback {jabber.deliver(message.from, "Done")} worker.process end.notify ... endend
class Worker include EM::Deferrable
def process ... set_deferred_status :succeeded endend
Plugins 1/3
PluginFactory.load "plugins"...def PluginFactory.load( dirname ) Dir.open( dirname ).each do |fn| next unless ( fn =~ /[.]rb$/ ) require "#{dirname}/#{fn}" endend
Plugins 2/3
class Plugin include EM::Deferrable
def process( args = {} ) sleep(0.05) set_deferred_status :succeeded endend
Plugins 3/3class NickPlugin < Plugin def process(args = {}) begin ... set_deferred_status :succeeded rescue set_deferred_status :failed end endend
class NickFactory < PluginFactoryINFO=<<INFOverb: NICKauthor: Stoyan Zhekovdescription: Get or set the nickname for some userINFO def create() return NickPlugin.new() endend
Simple API (json)
• /users - list of users
• /user/<nick>/<secret> - info for user
• /status/<nick>/<secret> - presence
• /micros/<page>/<format> - list of micros
• /micro/<id>/<secret> - micro + comments
Web (Ramaze)
class MainController < Ramaze::Controller def u nick begin @user = User.find_by_user(nick) subset = @user.micros.reverse @micros, @pager = paginate(subset, :limit => PAGE) rescue Exception => e flash[:error] = "Error: #{e.to_s}" redirect :/, :status => 302 end endend
<Demo>
To Do
• Commands parser - Ragel?
• OAuth or http://xmppid.net/
• TokyoCabinet
• XMPP Component - http://github.com/julien51/babylon
• Real PubSub?
Conclusion
• XMPP - good, open protocol
• xmpp4r-simple - good, easy to use
• eventmachine - good network library
• sequel - good ORM
• ramaze - good web apps framework
Questions?
</stream:stream>