Det er flere måter å legge til push-funksjonalitet til et program, inkludert Pushr og Pub-Nub, som er ganske elegante og enkle løsninger. Det er også noen mer avanserte alternativer. I denne artikkelen skal jeg vise deg hvordan du bruker Faye, et meldingssystem som kjører både på Ruby og Node.js.
Vi skal bygge en enkel chat-tjeneste. Nå, Ryan Bates dekket dette på Railscast # 260, men vi skal ta en litt annen tilnærming i denne opplæringen. Først skal vi opprette en chat-tjeneste der brukerne går inn i et offentligt rom, og alle kan chatte med hverandre offentlig. Den andre funksjonaliteten vi legger til, er private meldinger. I tillegg integrerer vi litt sikkerhet i implementeringen vår ved hjelp av Ryan Bates private_pub perle.
Pass på at du har et arbeidssett oppsett av Ruby, og Ruby on Rails 3.1. Bortsett fra det, trenger du tynn. Tynn er en mye brukt Ruby webserver, og Faye krever at den kjører (det virker ikke med WEBrick, Rails 'innebygde server). Du kan installere Tynn, slik som:
perle installasjon tynn
Vi burde være alle satt, så la oss lage programmet:
skinner ny faye-opplæring
Nå legger du til faye
perle til din Gemfile
:
perle 'faye'
og løp bunt installasjon
å installere den. Faye må kjøre på en egen webserver fra selve webapplikasjonen; For å oppnå dette må du opprette en Rackup config-fil. Legg til en faye.ru
fil til roten av prosjektet og sørg for at det ser ut slik:
krever 'faye' bayeux = Faye :: RackAdapter.new (: mount => '/ faye',: timeout => 25) bayeux.listen (9292)
Denne filen forteller bare Rackup hvordan du starter Faye-serveren. Prøv det for å sikre at det fungerer riktig. Kjør dette i Terminal:
rackup faye.ru -E produksjon - er tynn
Hvis du ikke mottar noen feil, så er du god til å gå!
For å opprette et chatprogram trenger vi to grunnleggende ting: brukere og et chatrom. Vi skal ikke godkjenne våre brukere, men vi må fortsatt gi dem en måte å angi brukernavn på. La oss lage det. Kjør følgende kommando for å lage en økt kontrolleren
slik at vi kan logge dem inn
skinner g kontroller økter nye skape
Dette vil skape en økt kontrolleren
og to metoder: ny
og skape
. Legg til disse ruter til din routes.rb
fil:
få '/ login' => 'økter # nytt',: som =>: innloggingspost '/ login' => 'økter # opprett',: som =>: logg inn
Disse to rutene bør være selvforklarende for deg. Gå videre og endre app / visninger / økter / new.html.erb
fil:
<%= form_tag login_path do |f| %> <%= label_tag :username %> <%= text_field_tag :username %> <%= submit_tag "Enter" %> <% end %>
Og ha skape
metode i øktene kontrolleren
ser ut som følgende:
def opprett økt [: brukernavn] = params [: brukernavn] gjengi: text => "Velkommen # session [: brukernavn]!" slutt
Gå ut og prøv det! Løpe skinner server
i terminalen og peker nettleseren din til localhost: 3000 / logg inn og skriv inn et brukernavn. Du bør bli møtt av søknaden din etter at du har sendt inn skjemaet.
Hvis du er ute etter en utfordring, kan du bruke Omniauth til å legge til Twitter eller Facebook-integrasjon for dette trinnet!
Nå som vi har noen grunnleggende godkjenning, la oss legge til et chatrom. Kjør følgende kommando for å opprette en chat kontrolleren
:
skinner genererer kontroller chat-rom
Dette vil generere våre chatter kontrolleren
og en rom
metode. Vi må legge til noen ruter for å gjøre vårt chat-arbeid, så legg til denne linjen til din routes.rb
fil:
få '/ chatroom' => 'chats # room',: as =>: chat
Denne ruten vil lede brukeren vår til chatterommet, og la dem legge inn meldinger via en enkel skjema. Endre rom
metode på chattene kontrolleren
og få det til å se slik ut:
def room redirect_to login_path med mindre økten [: brukernavn] slutter
Dette vil sikre at brukerne angir et brukernavn hvis de vil chatte. La oss nå lage rommet selv! Legg dette til i app / visninger / samtaler / room.html.erb
:
Velkommen til chatterommet <%= session[:username] %>!
Dette er en enkel struktur for rommet. Skjemaet på slutten vil bli administrert av noen JavaScript-kode som vil publisere meldingen til chatterommet.
Nå, for å legge inn meldinger til rommet, må vi legge til noe JavaScript til vår visning. Først legger du til Fayes bibliotek til app / visninger / oppsett / application.html.erb
:
<%= javascript_include_tag "http://localhost:9292/faye.js" %>
Deretter legger du til følgende i begynnelsen av room.html.erb
utsikt:
Denne metoden tar meldingen i skjemaet vi la til tidligere (når det er sendt inn), og sender forfatterens brukernavn og melding til "/ meldinger / offentlig" -kanalen i et JSON-objekt. Kanaler er Fayes måte å sende meldinger på. En bruker abonnerer på en kanal og mottar alle meldinger som sendes til den. I vårt tilfelle er det bare én kanal, som er den offentlige. La oss dissekere koden litt mer:
returner falsk
, for å unngå at skjemaet faktisk sendes inn og forfriskende siden.Nå vil dette publisere meldinger til chatrommet, men våre tilkoblede brukere kan ikke motta dem, fordi nettleserne ikke abonnerer på kanalen. Dette oppnås gjennom litt mer JavaScript. Gjør JavaScript-blokken på app / visninger / samtaler / room.html.erb
ser slik ut:
Dette kobler bare til Fayes server, og abonnerer på "/ meldinger / offentlig" -kanalen. Tilbakeringingen vi gir mottar meldingene som sendes. data
vil være JSON objektet vi publiserte før, så vi bruker bare det for å lage en
merk med meldingen inni, og legg det til chatterombeholderen.
Du bør nå ha en enkel samtale! Kjør både Faye og Rails-serveren, og åpne to nettlesere (eller et Incognito-vindu på Chrome for eksempel). Du kan skrive inn to forskjellige brukernavn og teste din chat. Meldinger skal vises nesten umiddelbart på chatterommet når du sender dem.
For øyeblikket kan brukerne chatte med hverandre, men alle meldinger er offentlige. La oss legge til litt enkel funksjonalitet der folk kan sende noen private meldinger, ved å nevne mottakerens brukernavn - som for eksempel i Twitter. For at dette skal fungere, skal vi abonnere våre brukere på egne kanaler, så de er de eneste som er i stand til å motta meldinger fra den. Lag din app / visninger / samtaler / room.html.erb
JavaScript ser slik ut:
Som du ser, abonnerer vi på to Faye-kanaler: den ene er den offentlige kanalen, og den andre er en kanal, kalt "/ meldinger / privat / USERNAME" (legg merke til at vi bruker brukernavnet på Railsøkten). På denne måten, når noen nevner den brukeren, i stedet for å sende meldingen via den offentlige kanalen, sender vi den via mottakerens private kanal, så bare den personen kan lese den. Vi legger også til noen enkle stiler til den, så den vises i fet skrift.
En annen ting som er endret, er koden som publiserer meldinger. Vi kontrollerer først om meldingen er privat, ved å bruke et enkelt regulært uttrykk som ser etter omtale. Hvis det er, publiserer vi en melding til mottakerens spesifikke kanal. Hvis ikke, gjør vi akkurat som vi gjorde før - publiser den til den offentlige kanalen.
Prøv det nå! Send meldinger til andre brukere ved å nevne dem, du bør bare se dem i mottakerens chatvindu.
Denne gjennomføringen har sine feil. Først sjekker vi ikke for å se om brukernavnet en person velger, er allerede i bruk. Dette ville bety at alle kunne skrive inn samme brukernavn som noen andre og sende meldinger som utgir seg til å være dem, og til og med motta sine private meldinger! Dette løses lett ved å legge til et slags autentiseringssystem eller ved å lagre brukernavnene som er i bruk, i en database. Jeg skal ikke dekke dette i dagens veiledning, men det bør være ganske enkelt for deg å implementere. Hvis du trenger hjelp, legg igjen en kommentar, og vi hjelper!
Den andre advarselen er ikke så åpenbar. Problemet med implementeringen er at alle kan manipulere JavaScript på fluen (ved hjelp av Firebug for eksempel) for å abonnere på hvilken kanal de ønsker (selv private kanaler), og de kan publisere meldinger til dem som utgir seg for å være noen andre. Dette er ikke like lett løst som den første feilen jeg pekte på (hvis vi skulle løse dette manuelt), men Ryan Bates opprettet en perle som gjør denne oppgaven til en film, og vår app er veldig sikker.
Perlen heter privat_pub; det forbyder i hovedsak alle brukere fra å publisere til kanaler med JavaScript, noe som betyr at bare Rails-appen kan publisere til dem. Dette legger til noe sikkerhet siden en ondsinnet bruker ikke ville kunne publisere til private kanaler. En annen ting som denne perlen løser er abonnementer. Med private_pub kan en bruker kun motta meldinger fra kanaler vi abonnerer på, slik at de ikke kan legge til et abonnement manuelt, og løse hele problemet.
Så la oss legge det til vår Gemfile
:
perle 'private_pub',: git => 'git: //github.com/ryanb/private_pub.git'
løpe bunt installasjon
å installere perlen og kjøre generatoren for å lage konfigurasjonsfilene:
skinner g private_pub: installer
Du vil motta en konfliktvarsel når du kjører denne kommandoen (private_pub prøver å overskrive faye.ru
fil). Skriv bare "Y" og trykk enter, da det er nødvendig å overskrive den filen. Du må også flytte offentlige / private_pub.js
fil til app / eiendeler / javascripts
mappe. Og det siste: Fjern linjen som inneholder faye.js
på application.html.erb
, siden Private Pub inkluderer det automatisk. Pass på at du starter begge serverne (skinner og faye) på dette tidspunktet.
Nå må vi gjøre noen endringer. For det første, abonnerer en bruker på en kanal, gjøres annerledes med private_pub. Redigere app / visninger / samtaler / room.html.erb
og legg til følgende før JavaScript-blokken:
<%= subscribe_to "/messages/public" %> <%= subscribe_to "/messages/private/#session[:username]" %>
Dette er private_pub
sin måte å abonnere på kanaler. Dette tillater brukeren å motta meldinger via kanalen du angir. Nå må vi endre JavaScript-koden til følgende:
PrivatePub.subscribe ("/ messages / public", funksjon (data)
$ (''). html (data.username + ":" + data.msg) .appendTo ('# chat_room');
);
PrivatePub.subscribe ( "/ meldinger / privat /<%= session[:username] %>", funksjon (data)
$ (''). addClass ('private'). html (data.username + ":" + data.msg) .appendTo ('# chat_room');
);
Den eneste forskjellen er at vi bruker PrivatePub til å abonnere på kanaler i stedet for Faye-biblioteket direkte.
Vi skal også endre måten vi publiserer meldinger på. Med Private Pub kan kun Rails søknaden publisere meldinger. Javascript-biblioteket kan ikke publisere meldinger på egenhånd. Dette er en god ting, siden vi tar full kontroll over hvem som publiserer meldinger og hvilken kanal. For å gjøre dette, må vi endre skjemaet som brukes til å sende meldinger til følgende:
<%= form_tag new_message_path, :remote => sant gjør%> <%= text_field_tag :message %> <%= submit_tag "Send" %> <% end %>
Dette er et AJAX-skjema, så det vil ikke oppdatere siden når det sendes inn. Det skal også være på jakt etter new_message_path
, så vær sikker på at du legger til dette til routes.rb
:
post '/ new_message' => 'chats # new_message',: as =>: new_message
Du skal også opprette en ny metode på chat-kontrolleren:
def new_message # Sjekk om meldingen er privat hvis mottaker = params [: message] .match (/@(.+) (. +) /) # Det er privat, send det til mottakerens private kanal @channel = "/ messages /private/#recipient.captures.first "@message = : userername => økt [: brukernavn],: msg => recipient.captures.second else # Det er offentlig, så send den til den offentlige kanalen @ channel = "/ messages / public" @message = : username => økt [: brukernavn],: msg => params [: message] avslutte respond_to do | f | f.js endeend
Dette fungerer veldig mye som sin JavaScript-motpart. Det avgjør om meldingen inneholder en omtale, og hvis den gjør det, sender den meldingen til mottakerens private kanal. Hvis ikke, sender den meldingen via den offentlige kanalen. Nå sender dette ikke egentlig meldingen, det skaper bare to variabler som vi trenger å bruke fra utsikten for å sende en. Private Pub tillater ikke at du sender meldinger via kontrolleren
(i hvert fall ikke med versjonen jeg brukte til denne opplæringen), så fortsett og lag filen app / visninger / samtaler / new_message.js.erb
og legg til følgende:
// Clear message input $ ('# message'). Val ("); // Send meldingen <% publish_to @channel, @message %>
Dette vil utføre den første linjen med kode, rydde meldingsboksen og ved å ringe publish_to
, Private Pub vil sende @budskap
(som vil bli konvertert til et JSON objekt når det kommer) til @kanal
. Enkelt, hei?
Fortsett å prøve det ut. Det skal fungere som før, bare med ny, ekstra sikkerhet!
Jeg håper denne artikkelen ga deg litt innsikt i hvordan du bruker Faye til dine prosjekter. Jeg vil anbefale at du alltid bruker Private Pub, siden det legger til et viktig sikkerhetsnivå, med mindre du ikke virkelig trenger det.
Hvis du har spørsmål, kan du spørre dem i kommentarene eller sende meg en tweet!