In deel I van deze serie, zag je hoe we een eenvoudige mobiele app in het Corona-raamwerk maakten die reageert op een "bump" -achtige actie (een "dreun" genoemd) om een bericht naar een ander mobiel apparaat te verzenden. De communicatie tussen de twee mobiele apparaten vindt plaats tussen een intermediair serverproces dat overeenkomt met twee "bonsde" apparaten op basis van tijdstempel en afstand. In deze zelfstudie zullen we het intermediaire serverproces instellen met Ruby on Rails.
Laten we beginnen met het creëren van ons project. Omdat we de geokit-plug-in gebruiken om te helpen met onze georuimtelijke berekeningen, moeten we dit project maken in Rails 2.3.5 omdat de plug-in niet 3.0-compatibel is.
Na het inloggen op uw server / hosting account (in ons geval gebruiken we Heroku), typt u het volgende:
mkdir dreun-server cd dreun-server / rails. verwijder public / index.html
De bovenstaande uitspraken zullen een map maken en een nieuw railsproject erin starten. Als u 3.0 op uw ontwikkelmachine hebt geïnstalleerd, moet u misschien RVM installeren en een afzonderlijke edelsteenset voor dit project maken. Dit doen is echter buiten het bestek van de zelfstudie. Laten we nu de geokit-plug-in installeren.
script / plugin installeer git: //github.com/andre/geokit-rails.git
Zodra dit is voltooid, moeten we onze edelsteen toevoegen aan het project in de Rails :: Initializer.run do | config | blok van ons environment.rb bestand:
config.gem "geokit"
Nu deze plug-in aan het project is toegevoegd, moeten we een hark-opdracht uitvoeren om te controleren of alle vereiste edelstenen in ons systeem zijn geïnstalleerd.
rake edelstenen: installeer
Geokit vertrouwt op de database om een aantal vrij geavanceerde afstandsberekeningen uit te voeren. Vanwege dit, zal de standaard SQLite-database die een rails-project wordt geleverd niet werken. Geokit vereist dat we ofwel een mysql of postgres db gebruiken om onze gegevens op te slaan. Hoewel heroku standaard postgres gebruikt, is het meer gebruikelijk dat ontwikkelaars mysql hebben geïnstalleerd. Het mooie van het gebruik van Rails en ActiveRecord is dat het er niet toe doet. We kunnen onze app met MySQL ontwikkelen en het zal naadloos samenwerken met postgres.
mysql -u root create database thumpserver;
Nu zullen we ons database.yml-bestand updaten om naar onze nieuw gemaakte ontwikkelingsdatabase "thumpserver" te wijzen.
ontwikkeling: adapter: mysql database: thumpserver gebruiker: root socket: /tmp/mysql.sock pool: 5 time-out: 5000
Eindelijk is ons projectcreatieproces voltooid. We kunnen beginnen met het coderen van de logica in onze thumpserver.
Rails heeft een eenvoudige generatormethode die een REST-gebaseerde bron voor gegevens CRUD maakt. Als die laatste zin niet klopte, raad ik je aan Google te 'liken naar rustgevende bronnen' om meer te weten te komen. In wezen met één opdracht kunnen we een databasetabel, model, controller en routes binnen het project creëren.
./ script / resource maken thump deviceid: string lat: decimal lng: decimal message: string received: boolean
Onze bron wordt thump genoemd, dus door deze op deze manier te genereren, is deze beschikbaar op de url / thump zodra onze server wordt uitgevoerd. We hebben 5 velden opgegeven die moeten worden gemaakt voor onze databasetabel:
deviceid: de UID van het mobiele apparaat
lat: latitude geboden door de locatieservice
lng: lengtegraad
bericht: het bericht dat wordt verzonden naar de gebuikte gebruikers
ontvangen: dit is een boolean die moet worden gemarkeerd zodra een bericht is ontvangen, zodat het niet opnieuw kan worden verzonden
Rails zullen "automatisch" tijdstempelvelden maken, genaamd created_at en updated_at. We zullen created_at later gebruiken in ons voorbeeld.
Toen we onze bron genereerden, werd een migratiebestand voor railsdatabases gemaakt in de map "db" van het project. De bestandsnaam zou ongeveer zo moeten lijken: TIMESTAMP_create_thumps.rb
We moeten dit bestand aanpassen om ervoor te zorgen dat onze locatie kan worden opgeslagen met voldoende decimalen. Om dit te doen vervang je eenvoudigweg deze twee regels:
t.decimal: lat t.decimal: lng
Met de volgende regels:
t.decimal: lat,: precision => 8,: scale => 8 t.decimal: lng,: precision => 8,: scale => 8
Dit zorgt ervoor dat onze velden voor lengte- en breedtegraden maximaal 8 decimalen bevatten.
Om te voorkomen dat het veld "received" in onze database NULL is, moeten we ook een instelling toevoegen zodat de waarde standaard false is. Nogmaals, we kunnen dit doen door deze regel te vervangen:
t.boolean: ontvangen
Met deze regel:
t.boolean: received,: default => false
Nu onze migratie is ingesteld, kunnen we de opdracht hark uitvoeren waarmee de tabel daadwerkelijk in de database wordt gemaakt:
rake db: migreren
Om inputs voor onze data in te nemen, zullen we de "create" -actie in onze thump-controller gebruiken. In aanvulling hierop hebben we een "zoekactie" nodig die enkele parameters in beslag neemt en door de database zoekt om overeen te komen met de twee gedempte apparaten. We moeten onze routes.rb aanpassen in de config-map om te reageren op de URL / thump / search op een GET-verzoek. We kunnen dit doen door deze regel te vervangen:
map.resources: dreunen
Met deze regel
map.resources: thumps,: collection => : search =>: get
Laten we de volgende regels toevoegen aan ons thump.rb-bestand in de app / modellen.
acts_as_mappable validates_presence_of: lat,: lng,: deviceid
De eerste regel maakt ons model "in kaart te brengen". Dit geeft ons een aantal extra zoekmethoden om de afstand tussen twee coördinaatsets te berekenen. De volgende regel voegt een aantal eenvoudige validaties toe aan ons dreungegevensmodel om ervoor te zorgen dat wanneer we een melding krijgen dat het de juiste velden bevat.
Ten slotte kunnen we onze acties voor het maken en zoeken van gegevens in onze controller maken. Dankzij de schoonheid en eenvoud van ActiveRecord is onze actie "creëren" nogal eenvoudig:
def maak Thump.create! (params [: thump]) render (: json => : succes => true) rescue render (: json => : success => false) einde
In het geval dat onze validaties falen, retourneren we een json-object met: success => false. In deel III van de tutorial zullen we onze mobiele app uitbreiden om hier rekening mee te houden.
Onze zoekactie "actie" is iets complexer, omdat het gebruik maakt van enkele van de hulpvragen van geokit:
def search thump = Thump.find (: first,: origin => [params [: thump] [: lat], params [: thump] [: lng]],: conditions => ["deviceid! =? AND ontvangen = ? ", params [: thump] [: deviceid], false],: order => 'distance asc, created_at desc') raise tenzij (thump) thump.update_attribute (: received, true) render (: json => : success => true,: message => thump.message) rescue render (: json => : succes => false) einde
Laten we dit opsplitsen:
thump = Thump.find (: first,: origin => [params [: thump] [: lat], params [: thump] [: lng]],: conditions => ["deviceid! =? AND received =?" , params [: thump] [: deviceid], false],: order => 'distance asc, created_at desc')
In wezen vragen we naar onze "kloppende" match in de database. Een apparaat verzendt de eigen breedte- en lengtegraad die ons oorsprongspunt is. Onze voorwaarden zorgen ervoor dat we niet per ongeluk ons eigen apparaat vinden door onze eigen deviceid uit te sluiten van de resultaatset. We willen ook alleen naar kloppen zoeken waarbij het veld "ontvangen" onwaar is. Om de beste overeenkomst te vinden in zowel afstand als tijd, zullen we onze resultaten rangschikken op afstand tussen de 2 punten in stijgende volgorde (d.w.z. dichtstbijzijnde) en tijd gemaakt of gemaakt in aflopende volgorde om de meest recente te vinden. Het is natuurlijk een onwaarschijnlijke gebeurtenis dat er conflicterende 'dreunen' zullen zijn voor onze test-app, maar dit soort query kan een toepassing voor meerdere gebruikers ondersteunen als we wilden dat deze.
raise tenzij (thump) thump.update_attribute (: received, true) render (: json => : success => true,: message => thump.message)
Het commando verhogen verhoogt onze codevoortgang naar het reddingsblok dat zal terugkeren: succes => false als we geen overeenkomende dreun kunnen vinden. Dit zorgt ervoor dat onze mobiele app op zijn minst iets terug krijgt in het geval van een fout. Als het object bestaat, stellen we het veld 'received' in op true om ervoor te zorgen dat dit bericht niet wordt geëvenaard in een volgend dataverzoek. Onze renderinstructie retourneert een JSON-object dat door het apparaat dat de "dreun" ontvangt, wordt geïnterpreteerd.
Om dit uit te testen, kunnen we een opdracht in de Rails-console uitvoeren om een voorbeeldrecord te maken met een oorsprongspunt in New York City:
Thump.create (: deviceid => "B",: lat => 40.7141667,: lng => - 74.0063889,: message => "B")
Om een "kloppende" match te krijgen, of een succesvolle return, kunnen we eerst onze server starten op de standaard poort 3000:
./ Script / server
En klik vervolgens op de volgende URL:
http: // localhost: 3000 / dreunen / search dreun [DeviceID] = A & dreun [lat] = 40,7141667 & dreun [lng] = -74,0063889
Als alles goed gaat, zou de browser het volgende moeten weergeven:
"Message": "B", "succes": true
Dit simuleert een apparaat genaamd "A" dat een "bons" bericht ontvangt van apparaat B. En daar hebben we het!
We zijn op de hoogte gebleven van deel III van deze serie, waar we de server-app naar Heroku zullen pushen en onze mobiele app upgraden om met de server te communiceren.