Dans la partie I de cette série, vous avez vu comment nous avons créé une application mobile simple dans le cadre Corona qui répond à une action semblable à celle d'un "choc" ("un coup") pour envoyer un message à un autre appareil mobile. La communication entre les deux appareils mobiles se produit entre un processus serveur intermédiaire qui fait correspondre deux appareils "frappés" par l'horodatage et la distance. Dans ce tutoriel, nous allons configurer le processus du serveur intermédiaire avec Ruby on Rails.
Commençons par créer notre projet. Puisque nous allons utiliser le plugin geokit pour nous aider dans nos calculs géospatiaux, nous devons créer ce projet dans Rails 2.3.5 car le plugin n'est pas compatible avec la version 3.0..
Après vous être connecté à votre compte serveur / hébergement (dans notre cas, nous utilisons Heroku), tapez ce qui suit:
mkdir thump-server cd thump-server / rails. remove public / index.html
Les instructions ci-dessus vont créer un répertoire et démarrer un nouveau projet de rails à l'intérieur de celui-ci. Si vous avez 3.0 installé sur votre machine de développement, vous devrez peut-être installer RVM et créer un gemset distinct pour ce projet. Cependant, cela sort du cadre du tutoriel. Maintenant, installons le plugin geokit.
script / plugin installer git: //github.com/andre/geokit-rails.git
Une fois cette opération terminée, nous devons ajouter notre gemme au projet dans Rails :: Initializer.run do | config | bloc de notre fichier environment.rb:
config.gem "geokit"
Maintenant que ce plugin a été ajouté au projet, nous devons exécuter une commande rake pour nous assurer que tous les gems requis sont installés sur notre système..
rake gems: installer
Geokit s'appuie sur la base de données pour effectuer des calculs de distance plutôt sophistiqués. De ce fait, la base de données SQLite par défaut fournie avec un projet rails ne fonctionnera pas. Geokit exige que nous utilisions une base de données mysql ou postgres pour stocker nos données. Bien que heroku utilise postgres par défaut, il est plus courant que les machines de développement aient installé mysql. L'utilisation de Rails et d'ActiveRecord présente l'avantage d'être sans importance. Nous pouvons développer notre application avec MySQL et cela fonctionnera de manière transparente avec postgres.
mysql -u root crée la base de données thumpserver;
Nous allons maintenant mettre à jour notre fichier database.yml pour qu'il pointe vers notre nouvelle base de développement "thumpserver"..
développement: adaptateur: base de données mysql: utilisateur de serveur Thumpserver: socket racine: /tmp/mysql.sock pool: 5 délai d'attente: 5 000
Enfin, notre processus de création de projet est terminé. Nous pouvons commencer à coder la logique à l'intérieur de notre serveur de serveur.
Rails a une méthode de générateur simple qui crée une ressource basée sur REST pour les données CRUD. Si cette dernière phrase n’a aucun sens, je vous suggère de rechercher des «ressources reposantes» dans Google pour en savoir plus. En une seule commande, nous pouvons créer une table de base de données, un modèle, un contrôleur et des itinéraires dans le projet..
./ script / générer une ressource thump deviceid: string lat: decimal lng: decimal message: string receive: boolean
Notre ressource s'appelle thump, donc en la générant de cette manière, elle sera disponible à l'url / thump une fois que notre serveur sera en marche. Nous avons spécifié 5 champs à créer pour notre table de base de données:
deviceid: l'UID du périphérique mobile
lat: latitude fournie par le service de localisation
lng: longitude
message: le message qui sera transmis aux utilisateurs qui ont tapé
receive: c'est un booléen pour marquer une fois qu'un message a été reçu afin qu'il ne puisse plus être envoyé
Rails créera "automatiquement" des champs d'horodatage appelés created_at et updated_at. Nous utiliserons created_at plus tard dans notre exemple.
Lorsque nous avons généré notre ressource, un fichier de migration de base de données Rails a été créé dans le dossier "db" du projet. Le nom du fichier devrait ressembler à ceci: TIMESTAMP_create_thumps.rb
Nous devons modifier ce fichier pour nous assurer que notre emplacement peut être stocké avec suffisamment de décimales. Pour ce faire, il suffit de remplacer ces deux lignes:
t.decimal: lat t.decimal: lng
Avec les lignes suivantes:
t.decimal: lat,: precision => 8,: scale => 8 t.decimal: lng,: precision => 8,: scale => 8
Cela garantira que nos champs de latitude et de longitude peuvent contenir au plus 8 décimales..
De plus, pour éviter que le champ "reçu" dans notre base de données soit NULL, nous devons ajouter un paramètre afin que sa valeur soit false par défaut. Encore une fois, nous pouvons le faire en remplaçant cette ligne:
t.boolean: reçu
Avec cette ligne:
t.boolean: receive,: default => false
Maintenant que notre migration est configurée, nous pouvons exécuter la commande rake qui créera la table dans la base de données:
rake db: migrer
Pour prendre des données pour nos données, nous utiliserons l'action "create" dans notre contrôleur thump. En plus de cela, nous avons besoin d'une action de "recherche" qui prendra certains paramètres et recherchera dans la base de données pour faire correspondre les deux périphériques frappés. Nous devons modifier notre fichier routes.rb dans le répertoire config pour répondre à l'URL / thump / search lors d'une demande GET. Nous pouvons le faire en remplaçant cette ligne:
map.resources: coups
Avec cette ligne
map.resources: thumps,: collection => : search =>: get
Ensuite, ajoutons les lignes suivantes à notre fichier thump.rb dans app / models.
acts_as_mappable validates_presence_of: lat,: lng,: deviceid
La première ligne rend notre modèle "mappable". Cela nous donne quelques méthodes de requête supplémentaires pour nous aider à calculer la distance entre deux jeux de coordonnées. La ligne suivante ajoute quelques validations simples à notre modèle de données thump pour garantir que, lorsque nous recevons un message thump, il contienne les champs appropriés..
Enfin, nous créons nos actions pour créer et rechercher des données dans notre contrôleur. Grâce à la beauté et à la simplicité d'ActiveRecord, notre action "créer" est assez simple:
def create Thump.create! (params [: thump]) render (: json => : success => true) rescue render (: json => : success => false) fin
Si nos validations échouent, nous renverrons un objet JSON avec: success => false. Dans la partie III du didacticiel, nous allons développer notre application mobile pour en tenir compte..
Notre recherche "action" est légèrement plus complexe car elle utilise certains des assistants de requête de geokit:
def search thump = Thump.find (: premier,: origine => [params [: thump] [: lat], params [: thump] [: lng]],: conditions => ["deviceid! =? AND reçu = ? ", params [: thump] [: deviceid], false],: order => 'distance asc, created_at desc') augmente sauf si (thump) thump.update_attribute (: reçu, vrai) est rendu (: json => : success => true,: message => thump.message) rescue render (: json => : success => false) fin
Décomposons ceci:
thump = Thump.find (: premier,: origine => [params [: thump] [: lat], params [: thump] [: lng]],: conditions => ["deviceid! =? AND reçu =?" , params [: thump] [: deviceid], false],: order => 'distance asc, created_at desc')
Essentiellement, nous interrogeons notre correspondance "thump" dans la base de données. Un appareil enverra ses propres latitude et longitude, qui seront notre point d'origine. Nos conditions garantissent que nous ne trouvons pas accidentellement notre propre appareil en excluant notre propre ID de périphérique du jeu de résultats. Nous souhaitons également uniquement effectuer des recherches dans les champs où le champ "reçu" est faux. Pour trouver la correspondance la plus proche en distance et en temps, nous allons classer nos résultats en fonction de la distance entre les 2 points par ordre croissant (c'est-à-dire le plus proche) et du temps créé ou créé par ordre décroissant pour trouver le plus récent. Évidemment, il est peu probable que notre application de test génère des "heurts" contradictoires, mais ce type de requête peut contenir jusqu'à une application multi-utilisateur si nous le souhaitions..
relance à moins que (thump) thump.update_attribute (: receive, true) rende (: json => : success => true,: message => thump.message)
La commande raise relèvera notre progression de code dans le bloc de secours qui retournera: success => false si nous ne pouvons pas trouver un bruit correspondant. Cela garantira que notre application mobile recevra au moins quelque chose en cas d'erreur. Si l'objet existe, nous allons définir le champ "reçu" sur true pour nous assurer que ce message ne sera pas mis en correspondance dans une demande de données ultérieure. Notre déclaration de rendu renverra un objet JSON que le périphérique recevant le "coup de poing" interprétera.
Pour tester cela, nous pouvons exécuter une commande dans la console Rails pour créer un exemple d'enregistrement avec un point d'origine de New York:
Thump.create (: deviceid => "B",: lat => 40.7141667,: lng => - 74.0063889,: message => "B")
Pour obtenir une correspondance exacte ou un retour réussi, nous pouvons d’abord démarrer notre serveur sur le port 3000 par défaut:
./ script / serveur
Et puis cliquez sur l'URL suivante:
http: // localhost: 3000 / thumps / search? thump [deviceid] = A & thump [lat] = 40.7141667 & thump [lng] = -74.0063889
Si tout se passe bien, le navigateur devrait afficher les informations suivantes:
"message": "B", "success": true
Ceci simule un périphérique appelé "A" recevant un message "sourd" de la part du périphérique B. Et nous l'avons!
Resté à l'écoute pour la partie III de cette série, où nous allons pousser l'application serveur vers Heroku et mettre à niveau notre application mobile pour communiquer avec le serveur.