1/* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19var PROTO_PATH = __dirname + '/../../../protos/route_guide.proto'; 20 21var async = require('async'); 22var fs = require('fs'); 23var parseArgs = require('minimist'); 24var path = require('path'); 25var _ = require('lodash'); 26var grpc = require('grpc'); 27var protoLoader = require('@grpc/proto-loader'); 28var packageDefinition = protoLoader.loadSync( 29 PROTO_PATH, 30 {keepCase: true, 31 longs: String, 32 enums: String, 33 defaults: true, 34 oneofs: true 35 }); 36var routeguide = grpc.loadPackageDefinition(packageDefinition).routeguide; 37var client = new routeguide.RouteGuide('localhost:50051', 38 grpc.credentials.createInsecure()); 39 40var COORD_FACTOR = 1e7; 41 42/** 43 * Run the getFeature demo. Calls getFeature with a point known to have a 44 * feature and a point known not to have a feature. 45 * @param {function} callback Called when this demo is complete 46 */ 47function runGetFeature(callback) { 48 var next = _.after(2, callback); 49 function featureCallback(error, feature) { 50 if (error) { 51 callback(error); 52 return; 53 } 54 if (feature.name === '') { 55 console.log('Found no feature at ' + 56 feature.location.latitude/COORD_FACTOR + ', ' + 57 feature.location.longitude/COORD_FACTOR); 58 } else { 59 console.log('Found feature called "' + feature.name + '" at ' + 60 feature.location.latitude/COORD_FACTOR + ', ' + 61 feature.location.longitude/COORD_FACTOR); 62 } 63 next(); 64 } 65 var point1 = { 66 latitude: 409146138, 67 longitude: -746188906 68 }; 69 var point2 = { 70 latitude: 0, 71 longitude: 0 72 }; 73 client.getFeature(point1, featureCallback); 74 client.getFeature(point2, featureCallback); 75} 76 77/** 78 * Run the listFeatures demo. Calls listFeatures with a rectangle containing all 79 * of the features in the pre-generated database. Prints each response as it 80 * comes in. 81 * @param {function} callback Called when this demo is complete 82 */ 83function runListFeatures(callback) { 84 var rectangle = { 85 lo: { 86 latitude: 400000000, 87 longitude: -750000000 88 }, 89 hi: { 90 latitude: 420000000, 91 longitude: -730000000 92 } 93 }; 94 console.log('Looking for features between 40, -75 and 42, -73'); 95 var call = client.listFeatures(rectangle); 96 call.on('data', function(feature) { 97 console.log('Found feature called "' + feature.name + '" at ' + 98 feature.location.latitude/COORD_FACTOR + ', ' + 99 feature.location.longitude/COORD_FACTOR); 100 }); 101 call.on('end', callback); 102} 103 104/** 105 * Run the recordRoute demo. Sends several randomly chosen points from the 106 * pre-generated feature database with a variable delay in between. Prints the 107 * statistics when they are sent from the server. 108 * @param {function} callback Called when this demo is complete 109 */ 110function runRecordRoute(callback) { 111 var argv = parseArgs(process.argv, { 112 string: 'db_path' 113 }); 114 fs.readFile(path.resolve(argv.db_path), function(err, data) { 115 if (err) { 116 callback(err); 117 return; 118 } 119 var feature_list = JSON.parse(data); 120 121 var num_points = 10; 122 var call = client.recordRoute(function(error, stats) { 123 if (error) { 124 callback(error); 125 return; 126 } 127 console.log('Finished trip with', stats.point_count, 'points'); 128 console.log('Passed', stats.feature_count, 'features'); 129 console.log('Travelled', stats.distance, 'meters'); 130 console.log('It took', stats.elapsed_time, 'seconds'); 131 callback(); 132 }); 133 /** 134 * Constructs a function that asynchronously sends the given point and then 135 * delays sending its callback 136 * @param {number} lat The latitude to send 137 * @param {number} lng The longitude to send 138 * @return {function(function)} The function that sends the point 139 */ 140 function pointSender(lat, lng) { 141 /** 142 * Sends the point, then calls the callback after a delay 143 * @param {function} callback Called when complete 144 */ 145 return function(callback) { 146 console.log('Visiting point ' + lat/COORD_FACTOR + ', ' + 147 lng/COORD_FACTOR); 148 call.write({ 149 latitude: lat, 150 longitude: lng 151 }); 152 _.delay(callback, _.random(500, 1500)); 153 }; 154 } 155 var point_senders = []; 156 for (var i = 0; i < num_points; i++) { 157 var rand_point = feature_list[_.random(0, feature_list.length - 1)]; 158 point_senders[i] = pointSender(rand_point.location.latitude, 159 rand_point.location.longitude); 160 } 161 async.series(point_senders, function() { 162 call.end(); 163 }); 164 }); 165} 166 167/** 168 * Run the routeChat demo. Send some chat messages, and print any chat messages 169 * that are sent from the server. 170 * @param {function} callback Called when the demo is complete 171 */ 172function runRouteChat(callback) { 173 var call = client.routeChat(); 174 call.on('data', function(note) { 175 console.log('Got message "' + note.message + '" at ' + 176 note.location.latitude + ', ' + note.location.longitude); 177 }); 178 179 call.on('end', callback); 180 181 var notes = [{ 182 location: { 183 latitude: 0, 184 longitude: 0 185 }, 186 message: 'First message' 187 }, { 188 location: { 189 latitude: 0, 190 longitude: 1 191 }, 192 message: 'Second message' 193 }, { 194 location: { 195 latitude: 1, 196 longitude: 0 197 }, 198 message: 'Third message' 199 }, { 200 location: { 201 latitude: 0, 202 longitude: 0 203 }, 204 message: 'Fourth message' 205 }]; 206 for (var i = 0; i < notes.length; i++) { 207 var note = notes[i]; 208 console.log('Sending message "' + note.message + '" at ' + 209 note.location.latitude + ', ' + note.location.longitude); 210 call.write(note); 211 } 212 call.end(); 213} 214 215/** 216 * Run all of the demos in order 217 */ 218function main() { 219 async.series([ 220 runGetFeature, 221 runListFeatures, 222 runRecordRoute, 223 runRouteChat 224 ]); 225} 226 227if (require.main === module) { 228 main(); 229} 230 231exports.runGetFeature = runGetFeature; 232 233exports.runListFeatures = runListFeatures; 234 235exports.runRecordRoute = runRecordRoute; 236 237exports.runRouteChat = runRouteChat; 238