OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library dartiverse_search; | |
6 | |
7 import 'dart:async'; | |
8 import 'dart:convert'; | |
9 import 'dart:io'; | |
10 | |
11 import 'package:http_server/http_server.dart' as http_server; | |
12 import 'package:http/http.dart' as http_client; | |
13 import 'package:route/server.dart'; | |
14 import 'package:logging/logging.dart' show Logger, Level; | |
15 | |
16 part 'search_engine.dart'; | |
17 part 'stack_overflow_search_engine.dart'; | |
18 part 'github_search_engine.dart'; | |
19 | |
20 | |
21 final Logger log = new Logger('DartiverseSearch'); | |
22 | |
23 | |
24 // List of search-engines used. | |
25 final searchEngines = [ | |
26 new StackOverflowSearchEngine(), | |
27 new GithubSearchEngine() | |
28 ]; | |
29 | |
30 | |
31 /** | |
32 * Handle an established [WebSocket] connection. | |
33 * | |
34 * The web-socket can send search requests as JSON-formatted messages, | |
35 * that will be responded to with a series of results and finally a done | |
36 * message. | |
37 */ | |
38 void handleWebSocket(WebSocket webSocket) { | |
39 log.info('New web-socket connection'); | |
40 | |
41 // Listen for incoming data. We expect the data to be a JSON-encoded String. | |
42 webSocket | |
43 .map((string) => JSON.decode(string)) | |
44 .listen((json) { | |
45 // The JSON object should contains a 'request' entry. | |
46 var request = json['request']; | |
47 switch (request) { | |
48 case 'search': | |
49 // Initiate a new search. | |
50 var input = json['input']; | |
51 log.info("Searching for '$input'"); | |
52 int done = 0; | |
53 for (var engine in searchEngines) { | |
54 engine.search(input) | |
55 .listen((result) { | |
56 // The search-engine found a result. Sent it to the client. | |
57 log.info("Got result from ${engine.name} for '$input': " | |
58 "${result.title}"); | |
59 var response = { | |
60 'response': 'searchResult', | |
61 'source': engine.name, | |
62 'title': result.title, | |
63 'link': result.link | |
64 }; | |
65 webSocket.add(JSON.encode(response)); | |
66 }, onError: (error) { | |
67 log.warning("Error while searching on ${engine.name}: $error"); | |
68 },onDone: () { | |
69 done++; | |
70 if (done == searchEngines.length) { | |
71 // All search-engines are done. Send done message to the | |
72 // client. | |
73 webSocket.add(JSON.encode({ 'response': 'searchDone' })); | |
74 } | |
75 }); | |
76 } | |
77 break; | |
78 | |
79 default: | |
80 log.warning("Invalid request '$request'."); | |
81 } | |
82 }, onError: (error) { | |
83 log.warning('Bad WebSocket request'); | |
84 }); | |
85 } | |
86 | |
87 | |
88 void main() { | |
89 // Set up logger. | |
90 Logger.root.level = Level.ALL; | |
91 Logger.root.onRecord.listen((LogRecord rec) { | |
92 print('${rec.level.name}: ${rec.time}: ${rec.message}'); | |
93 }); | |
94 | |
95 var buildPath = Platform.script.resolve('build').toFilePath(); | |
96 if (!new Directory(buildPath).existsSync()) { | |
97 log.severe("The 'build/' directory was not found. Please run 'pub build'."); | |
98 return; | |
99 } | |
100 HttpServer.bind('0.0.0.0', 8080).then((server) { | |
101 log.info("Search server is running on " | |
102 "'http://${Platform.localHostname}:8080/'"); | |
103 var router = new Router(server); | |
104 | |
105 // The client will connect using a WebSocket. Upgrade requests to '/ws' and | |
106 // forward them to 'handleWebSocket'. | |
107 router.serve('/ws') | |
108 .transform(new WebSocketTransformer()) | |
109 .listen(handleWebSocket); | |
110 | |
111 // Set up default handler. This will serve files from our 'build' directory. | |
112 var virDir = new http_server.VirtualDirectory(buildPath); | |
113 // Disable jail-root, as packages are local sym-links. | |
114 virDir.jailRoot = false; | |
115 virDir.allowDirectoryListing = true; | |
116 virDir.directoryHandler = (dir, request) { | |
117 // Redirect directory-requests to index.html files. | |
118 var indexUri = new Uri.file(dir.path).resolve('index.html'); | |
119 virDir.serveFile(new File(indexUri.toFilePath()), request); | |
120 }; | |
121 virDir.serve(router.defaultStream); | |
122 }); | |
123 } | |
OLD | NEW |