criando um instant messenger

Post on 26-Jun-2015

2.095 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

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: Rails

• Distributed Ruby (DRb)

• Perguntas

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

• Descentralizado

Botando a mão na massa (i)

• O que é XMPP/Jabber

• Trocar XMLs via rede

• Autenticação e encriptação

• Descentralizado

• Extensível

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)

• XMPP

• JID

• Presence

• Messages

JID’s:vinibaggio@gmail.com/GTalk

vinibaggio@vinibaggio.com/Pidgin

Botando a mão na massa (iii)

• XMPP

• JID

• Presence

• Messages

Botando a mão na massa (iii)

• XMPP

• JID

• Presence

• Messages

<presence from='xxxxx@gmail.com' type='unavailable' to='vinibaggio@gmail.com/chattyAB9DA217' xmlns='jabber:client'/>

Botando a mão na massa (iii)

• XMPP

• JID

• Presence

• Messages

Botando a mão na massa (iii)

• XMPP

• JID

• Presence

• Messages

<message type='chat' to='xxxxxxx@gmail.com' xmlns='jabber:client'>

<body>Nao fuja!</body></message>

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 GoogleTalk

require ‘xmpp4r’

include JabberJabber::debug = true

jid = Jabber::JID.new ‘vinibaggio@gmail.com/Chatty’password = ‘*******’

client = Jabber::Client.new jidclient.connect ‘talk.google.com’client.auth passwordclient.send Presence.new@clients[email] = client

Trocando idéias com o GoogleTalk

require ‘xmpp4r’

include JabberJabber::debug = true

jid = Jabber::JID.new ‘vinibaggio@gmail.com/Chatty’password = ‘*******’

client = Jabber::Client.new jidclient.connect ‘talk.google.com’client.auth passwordclient.send Presence.new@clients[email] = client

Type: Status:nil (available) nil (available):error :away:probe :chat:subscribe :dnd:subscribed :xa:unavailable:unsubscribe:unsubscribed

Trocando idéias com o GoogleTalk

client.add_message_callback do |msg|unless msg.type == :error or msg.body.nil?

push_msg msgend

end

client.add_presence_callback do |presence|push_presence presence

end

Trocando idéias com o GoogleTalk

def push_msg(msg)from = msg.from.bare.to_sto = msg.to.bare.to_sbody = msg.body

new_msg = {:body => body, :from => from}@msg_stack[to].push new_msg

end

Trocando idéias com o GoogleTalkdef push_presence(presence)

from = presence.from.bare.to_sto = presence.to.bare.to_sif presence.type == :unavailable

status = :unavailableelse

status = presence.show || :availableendnew_presence = {:status => status, :from => from}@presence_stack[to].push new_presence

end

Trocando idéias com o GoogleTalk

client.close

Trocando idéias com o GoogleTalk

class XMPPConnectorinclude Singletondef 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;privatedef check_timeout; ...; end;def push_msg(msg); ...; end;def push_presence(msg); ...; end;

end

Trocando idéias com o GoogleTalk

connector = XMPPConnector.instancejid = 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);

Juntando tudo: Rails

Acabou a parte do XMPP!Vamos pro Rails!!

Juntando tudo: Railsrequire ‘xmppconnector’

class MessengerController < ApplicationControllerfilter_parameter_logging :passworddef login

email = params[:email]password = params[:password]xmpp = XMPPConnector.instancesession[:jid] = xmpp.login(email, password)render :action => ‘chat’

end...

end

check_updates

send_msg

vinibaggio

vinibaggio

****************

Pergunta fatídica...

Pergunta fatídica...

Does it scale?

Pergunta fatídica...

Does it scale?Nope.

mongrel simples

Request

dispatcherApp Rails

XMPP Layer

joao

maria

* vinibaggio

localhost:3000/login

MessengerController::login Messenger#login(vinibaggio)

OK:render => "chat"

localhost:3000/chat

Tipo de request: Login (Mongrel simples)

mod_rails (Passenger)

Request

dispatcher

Instância

Rails 1

XMPP Layer 1

joao

maria

localhost:3000/login

localhost:3000/chat

Tipo de request: Login (mod_rails)

Instância

Rails 2

Instância

Rails 5

XMPP Layer 5

pedro

paulo

XMPP Layer 2

vitor

* vinibaggio

Messenger#login(vinibaggio)MessengerController::login

OK:render => "chat"

mod_rails (Passenger)

Request

dispatcher

Instância

Rails 1

XMPP Layer 1

joao

maria

localhost:3000/send_msg

localhost:3000/timeout

Tipo de request: Send_msg (mod_rails)

Instância

Rails 2

Instância

Rails 5

XMPP Layer 5

pedro

paulo

XMPP Layer 2

vitor

vinibaggio

Messenger#send_msg(vinibaggio)MessengerController::send_msg

ERROR

flash[:error] = "Invalid connection"

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.sizer << 1puts r.sizesleep 10

end

Cliente

Tempo

0s

5s

10s

15s

A

B

01

12

23

34

mod_rails

Request

dispatcher

Instância

Rails 1

RemoteXMPP

joao

maria

pedro

paulo

vitor

vinibaggio

Requests

Arquitetura com mod_rails + DRb

Instância

Rails 2

Instância

Rails 5

Response

require ‘drb’include ‘xmppconnector’DRb.start_service ‘druby://localhost:6666’,

XMPPConnector.instanceDRb.thread.join

Servidor XMPP + DRb

Rails + DRbrequire ‘xmppconnector’

class MessengerController < ApplicationControllerfilter_parameter_logging :passworddef login

...end

def xmppDRbObject.new nil, ‘druby://localhost:6666’

end...

end

That’s it!

• Relembrando...

• Biblioteca XMPP4R para XMPP

• Rails para fazer a interface

• Paralelizando a arquitetura

• Distributed Ruby (DRb)

Obrigado!!!

• Perguntas??

• Contato:

• vinibaggio@gmail.com

• www.vinibaggio.com

top related