Criando um Instant
Messenger com Rails
        Vinícius Baggio Fuentes
Agenda
• Experimentar: por que ruby e rails?
• Botando a mão na massa
• Trocando idéias com o GoogleTalk
• Juntando tudo: ...
Experimentar: por
   que ruby e rails?

• Because we can!
• Rápidos resultados
• Criatividade e liberdade
Experimentar: por
   que ruby e rails?

• Because we can!
• Rápidos resultados
• Criatividade e liberdade
Botando a mão na
      massa (i)

• O que é XMPP/Jabber
Botando a mão na
      massa (i)

• O que é XMPP/Jabber
 • Trocar XMLs via rede
Botando a mão na
      massa (i)

• O que é XMPP/Jabber
 • Trocar XMLs via rede
 • Autenticação e encriptação
Botando a mão na
      massa (i)

• O que é XMPP/Jabber
 • Trocar XMLs via rede
 • Autenticação e encriptação
 • Descentra...
Botando a mão na
      massa (i)

• O que é XMPP/Jabber
 • Trocar XMLs via rede
 • Autenticação e encriptação
 • Descentra...
Botando a mão na
      massa (ii)

• Usos do XMPP
Botando a mão na
      massa (ii)

• Usos do XMPP
 • Conversar
Botando a mão na
      massa (ii)

• Usos do XMPP
 • Conversar
 • Web Services
Botando a mão na
      massa (ii)

• Usos do XMPP
 • Conversar
 • Web Services
 • Robôs ajudantes
Botando a mão na
      massa (ii)

• Usos do XMPP
 • Conversar
 • Web Services
 • Robôs ajudantes
 • Manutenção e deploy
Botando a mão na
     massa (iii)

• XMPP
Botando a mão na
     massa (iii)

• XMPP
 • JID
Botando a mão na
     massa (iii)

• XMPP
 • JID
 • Presence
Botando a mão na
     massa (iii)

• XMPP
 • JID
 • Presence
 • Messages
Botando a mão na
       massa (iii)
                    JID’s:
         vinibaggio@gmail.com/GTalk
•   XMPP
      vinibagg...
Botando a mão na
     massa (iii)

• XMPP
 • JID
 • Presence
 • Messages
Botando a mão na
       massa (iii)
         <presence
         from='xxxxx@gmail.com'
         type='unavailable'
•   XMP...
Botando a mão na
     massa (iii)

• XMPP
 • JID
 • Presence
 • Messages
Botando a mão na
       massa (iii)
        <message type='chat'
        to='xxxxxxx@gmail.com'
•   XMPPxmlns='jabber:clie...
Botando a mão na
     massa (iii)

• XMPP
 • JID
 • Presence
 • Messages
Botando a mão na
     massa (iv)

• XMPP em Ruby:
Botando a mão na
     massa (iv)

• XMPP em Ruby:
 • XMPP4R
Botando a mão na
     massa (iv)

• XMPP em Ruby:
 • XMPP4R
 • XMPP4R::Simple
Botando a mão na
     massa (iv)

• XMPP em Ruby:
 • XMPP4R
 • XMPP4R::Simple
 • Net::XMPP
Trocando idéias com o
     GoogleTalk
Trocando idéias com o
require ‘xmpp4r’
               GoogleTalk
include Jabber
Jabber::debug = true

jid = Jabber::JID.ne...
Trocando idéias com o
require ‘xmpp4r’
                GoogleTalk
include Jabber
           Type:    Status:
Jabber::debug...
Trocando idéias com o
               GoogleTalk
client.add_message_callback do |msg|
 unless msg.type == :error or msg.bod...
Trocando idéias com o
        GoogleTalk
def push_msg(msg)
 from = msg.from.bare.to_s
 to = msg.to.bare.to_s
 body = msg.b...
Trocando idéias com o
               GoogleTalk
def push_presence(presence)
 from = presence.from.bare.to_s
 to = presence...
Trocando idéias com o
      GoogleTalk

client.close
Trocando idéias com o
class XMPPConnector
                 GoogleTalk
  include Singleton
  def login(email, password); .....
Trocando idéias com o
        GoogleTalk
connector = XMPPConnector.instance
jid = connector.login(‘vinibaggio@gmail.com’, ...
Juntando tudo: Rails

   Acabou a parte do XMPP!
       Vamos pro Rails!!
Juntando tudo: Rails
require ‘xmppconnector’

class MessengerController < ApplicationController
  filter_parameter_logging ...
send_msg


check_updates
vinibaggio
vinibaggio

****************
Pergunta fatídica...
Pergunta fatídica...

    Does it scale?
Pergunta fatídica...

    Does it scale?
       Nope.
Tipo de request: Login (Mongrel simples)

                                                         Messenger#login(vinibag...
Tipo de request: Login (mod_rails)

                                                          Messenger#login(vinibaggio)
...
Tipo de request: Send_msg (mod_rails)

                                                              Messenger#send_msg(vi...
Distributed Ruby!


• Remote Method Invocation (RMI)
• Standard library
• Access Control Lists (ACLs)
require ‘drb’
DRb.start_service ‘druby://localhost:6666’, []
DRb.thread.join


                         Servidor
require ‘drb’
r = DRbObject.new nil, ‘druby://localhost:6666’
while true
  puts r.size
  r << 1
  puts r.size
  sleep 10
e...
A
Tempo
        0
   0s
        1   B
            1
   5s
            2
        2
  10s
        3
            3
  15s
    ...
Arquitetura com mod_rails + DRb



                              Instância
                               Rails 1

       ...
require ‘drb’
include ‘xmppconnector’
DRb.start_service ‘druby://localhost:6666’,
              XMPPConnector.instance
DRb...
Rails + DRb
require ‘xmppconnector’

class MessengerController < ApplicationController
  filter_parameter_logging :password...
That’s it!

• Relembrando...
 • Biblioteca XMPP4R para XMPP
 • Rails para fazer a interface
 • Paralelizando a arquitetura...
Obrigado!!!

• Perguntas??
• Contato:
 • vinibaggio@gmail.com
 • www.vinibaggio.com
Criando um Instant Messenger
Criando um Instant Messenger
Criando um Instant Messenger
Criando um Instant Messenger
Upcoming SlideShare
Loading in …5
×

Criando um Instant Messenger

2,404 views

Published on

Essa é a minha palestra no evento Ruby + Rails no mundo real, falando sobre a criação de um instant messenger em ruby e rails.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,404
On SlideShare
0
From Embeds
0
Number of Embeds
168
Actions
Shares
0
Downloads
41
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Criando um Instant Messenger

  1. 1. Criando um Instant Messenger com Rails Vinícius Baggio Fuentes
  2. 2. Agenda • Experimentar: por que ruby e rails? • Botando a mão na massa • Trocando idéias com o GoogleTalk • Juntando tudo: Rails • Distributed Ruby (DRb) • Perguntas
  3. 3. Experimentar: por que ruby e rails? • Because we can! • Rápidos resultados • Criatividade e liberdade
  4. 4. Experimentar: por que ruby e rails? • Because we can! • Rápidos resultados • Criatividade e liberdade
  5. 5. Botando a mão na massa (i) • O que é XMPP/Jabber
  6. 6. Botando a mão na massa (i) • O que é XMPP/Jabber • Trocar XMLs via rede
  7. 7. Botando a mão na massa (i) • O que é XMPP/Jabber • Trocar XMLs via rede • Autenticação e encriptação
  8. 8. Botando a mão na massa (i) • O que é XMPP/Jabber • Trocar XMLs via rede • Autenticação e encriptação • Descentralizado
  9. 9. Botando a mão na massa (i) • O que é XMPP/Jabber • Trocar XMLs via rede • Autenticação e encriptação • Descentralizado • Extensível
  10. 10. Botando a mão na massa (ii) • Usos do XMPP
  11. 11. Botando a mão na massa (ii) • Usos do XMPP • Conversar
  12. 12. Botando a mão na massa (ii) • Usos do XMPP • Conversar • Web Services
  13. 13. Botando a mão na massa (ii) • Usos do XMPP • Conversar • Web Services • Robôs ajudantes
  14. 14. Botando a mão na massa (ii) • Usos do XMPP • Conversar • Web Services • Robôs ajudantes • Manutenção e deploy
  15. 15. Botando a mão na massa (iii) • XMPP
  16. 16. Botando a mão na massa (iii) • XMPP • JID
  17. 17. Botando a mão na massa (iii) • XMPP • JID • Presence
  18. 18. Botando a mão na massa (iii) • XMPP • JID • Presence • Messages
  19. 19. Botando a mão na massa (iii) JID’s: vinibaggio@gmail.com/GTalk • XMPP vinibaggio@vinibaggio.com/Pidgin • JID • Presence • Messages
  20. 20. Botando a mão na massa (iii) • XMPP • JID • Presence • Messages
  21. 21. Botando a mão na massa (iii) <presence from='xxxxx@gmail.com' type='unavailable' • XMPP to='vinibaggio@gmail.com/ •JID chattyAB9DA217' xmlns='jabber:client'/> • Presence • Messages
  22. 22. Botando a mão na massa (iii) • XMPP • JID • Presence • Messages
  23. 23. Botando a mão na massa (iii) <message type='chat' to='xxxxxxx@gmail.com' • XMPPxmlns='jabber:client'> <body>Nao fuja!</body> •JID </message> • Presence • Messages
  24. 24. Botando a mão na massa (iii) • XMPP • JID • Presence • Messages
  25. 25. Botando a mão na massa (iv) • XMPP em Ruby:
  26. 26. Botando a mão na massa (iv) • XMPP em Ruby: • XMPP4R
  27. 27. Botando a mão na massa (iv) • XMPP em Ruby: • XMPP4R • XMPP4R::Simple
  28. 28. Botando a mão na massa (iv) • XMPP em Ruby: • XMPP4R • XMPP4R::Simple • Net::XMPP
  29. 29. Trocando idéias com o GoogleTalk
  30. 30. Trocando idéias com o require ‘xmpp4r’ GoogleTalk include Jabber Jabber::debug = true jid = Jabber::JID.new ‘vinibaggio@gmail.com/Chatty’ password = ‘*******’ client = Jabber::Client.new jid client.connect ‘talk.google.com’ client.auth password client.send Presence.new @clients[email] = client
  31. 31. Trocando idéias com o require ‘xmpp4r’ GoogleTalk include Jabber Type: Status: Jabber::debug (available) nil = true nil (available) :error :away jid = Jabber::JID.new ‘vinibaggio@gmail.com/Chatty’ :probe :chat password = ‘*******’ :subscribe :dnd :subscribed :xa client = Jabber::Client.new jid :unavailable client.connect ‘talk.google.com’ :unsubscribe client.auth password :unsubscribed client.send Presence.new @clients[email] = client
  32. 32. Trocando idéias com o GoogleTalk client.add_message_callback do |msg| unless msg.type == :error or msg.body.nil? push_msg msg end end client.add_presence_callback do |presence| push_presence presence end
  33. 33. Trocando idéias com o GoogleTalk def push_msg(msg) from = msg.from.bare.to_s to = msg.to.bare.to_s body = msg.body new_msg = {:body => body, :from => from} @msg_stack[to].push new_msg end
  34. 34. Trocando idéias com o GoogleTalk def push_presence(presence) from = presence.from.bare.to_s to = presence.to.bare.to_s if presence.type == :unavailable status = :unavailable else status = presence.show || :available end new_presence = {:status => status, :from => from} @presence_stack[to].push new_presence end
  35. 35. Trocando idéias com o GoogleTalk client.close
  36. 36. Trocando idéias com o class XMPPConnector GoogleTalk include Singleton def login(email, password); ...; end; def get_presences(jid); ...; end; def get_messages(jid); ...; end; def send_message(jid, to, msg); ...; end; def set_status(jid, status); ...; end; def logout(jid); ...; end; private def check_timeout; ...; end; def push_msg(msg); ...; end; def push_presence(msg); ...; end; end
  37. 37. Trocando idéias com o GoogleTalk connector = XMPPConnector.instance jid = connector.login(‘vinibaggio@gmail.com’, ‘*****’) msgs = connector.get_messages(jid) presences = connector.get_presences(jid) connector.send_message(jid, ‘xxxx@gmail.com’, ‘Oi!’) connector.set.status(jid, :dnd);
  38. 38. Juntando tudo: Rails Acabou a parte do XMPP! Vamos pro Rails!!
  39. 39. Juntando tudo: Rails require ‘xmppconnector’ class MessengerController < ApplicationController filter_parameter_logging :password def login email = params[:email] password = params[:password] xmpp = XMPPConnector.instance session[:jid] = xmpp.login(email, password) render :action => ‘chat’ end ... end
  40. 40. send_msg check_updates
  41. 41. vinibaggio
  42. 42. vinibaggio ****************
  43. 43. Pergunta fatídica...
  44. 44. Pergunta fatídica... Does it scale?
  45. 45. Pergunta fatídica... Does it scale? Nope.
  46. 46. Tipo de request: Login (Mongrel simples) Messenger#login(vinibaggio) MessengerController::login localhost:3000/login XMPP Layer Request joao App Rails dispatcher maria * vinibaggio localhost:3000/chat :render => quot;chatquot; OK mongrel simples
  47. 47. Tipo de request: Login (mod_rails) Messenger#login(vinibaggio) MessengerController::login XMPP Layer 1 Instância joao Rails 1 maria XMPP Layer 2 Instância localhost:3000/login Request vitor Rails 2 * vinibaggio dispatcher localhost:3000/chat XMPP Layer 5 Instância pedro Rails 5 paulo :render => quot;chatquot; OK mod_rails (Passenger)
  48. 48. Tipo de request: Send_msg (mod_rails) Messenger#send_msg(vinibaggio) MessengerController::send_msg XMPP Layer 1 Instância joao Rails 1 maria ERROR XMPP Layer 2 Instância localhost:3000/send_msg Request vitor Rails 2 vinibaggio dispatcher localhost:3000/timeout flash[:error] = quot;Invalid connectionquot; XMPP Layer 5 Instância pedro Rails 5 paulo mod_rails (Passenger)
  49. 49. Distributed Ruby! • Remote Method Invocation (RMI) • Standard library • Access Control Lists (ACLs)
  50. 50. require ‘drb’ DRb.start_service ‘druby://localhost:6666’, [] DRb.thread.join Servidor
  51. 51. require ‘drb’ r = DRbObject.new nil, ‘druby://localhost:6666’ while true puts r.size r << 1 puts r.size sleep 10 end Cliente
  52. 52. A Tempo 0 0s 1 B 1 5s 2 2 10s 3 3 15s 4
  53. 53. Arquitetura com mod_rails + DRb Instância Rails 1 RemoteXMPP Requests Instância joao Request Rails 2 maria dispatcher pedro paulo Response vitor vinibaggio Instância Rails 5 mod_rails
  54. 54. require ‘drb’ include ‘xmppconnector’ DRb.start_service ‘druby://localhost:6666’, XMPPConnector.instance DRb.thread.join Servidor XMPP + DRb
  55. 55. Rails + DRb require ‘xmppconnector’ class MessengerController < ApplicationController filter_parameter_logging :password def login ... end def xmpp DRbObject.new nil, ‘druby://localhost:6666’ end ... end
  56. 56. That’s it! • Relembrando... • Biblioteca XMPP4R para XMPP • Rails para fazer a interface • Paralelizando a arquitetura • Distributed Ruby (DRb)
  57. 57. Obrigado!!! • Perguntas?? • Contato: • vinibaggio@gmail.com • www.vinibaggio.com

×