Example #1
0
        public void Start(Book.Book book, CollectionSettings collectionSettings, Color backColor)
        {
            if (_wifiAdvertiser != null)
            {
                Stop();
            }

            // This listens for a BloomReader to request a book.
            // It requires a firewall hole allowing Bloom to receive messages on _portToListen.
            // We initialize it before starting the Advertiser to avoid any chance of a race condition
            // where a BloomReader manages to request an advertised book before we start the listener.
            _wifiListener = new BloomReaderUDPListener();
            _wifiListener.NewMessageReceived += (sender, args) =>
            {
                var json = Encoding.UTF8.GetString(args.Data);
                try
                {
                    dynamic settings = JsonConvert.DeserializeObject(json);
                    // The property names used here must match the ones in BloomReader, doInBackground method of SendMessage,
                    // a private class of NewBookListenerService.
                    var androidIpAddress = (string)settings.deviceAddress;

                    var androidName = (string)settings.deviceName;
                    // This prevents the device (or other devices) from queuing up requests while we're busy with this one.
                    // In effect, the Android is only allowed to request a retry after we've given up this try at sending.
                    // Of course, there are async effects from network latency. But if we do get another request while
                    // handling this one, we will ignore it, since StartSendBook checks for a transfer in progress.
                    _wifiAdvertiser.Paused = true;
                    StartSendBookOverWiFi(book, androidIpAddress, androidName, backColor);
                    // Returns immediately. But we don't resume advertisements until the async send completes.
                }
                // If there's something wrong with the JSON (maybe an obsolete or newer version of reader?)
                // just ignore the request.
                catch (Exception ex) when(ex is JsonReaderException || ex is JsonSerializationException)
                {
                    _progress.Error(id: "BadBookRequest",
                                    message: "Got a book request we could not process. Possibly the device is running an incompatible version of BloomReader?");

                    //this is too technical/hard to translate
                    _progress.ErrorWithoutLocalizing($" Request contains {json}; trying to interpret as JSON we got {ex.Message}");
                }
            };

            var pathHtmlFile = book.GetPathHtmlFile();

            _wifiAdvertiser = new WiFiAdvertiser(_progress)
            {
                BookTitle     = BookStorage.SanitizeNameForFileSystem(book.Title),             // must be the exact same name as the file we will send if requested
                TitleLanguage = collectionSettings.Language1Iso639Code,
                BookVersion   = Book.Book.MakeVersionCode(File.ReadAllText(pathHtmlFile), pathHtmlFile)
            };

            AndroidView.CheckBookLayout(book, _progress);
            _wifiAdvertiser.Start();

            _progress.Message(id: "WifiInstructions1",
                              message: "On the Android, run Bloom Reader, open the menu and choose 'Receive Books from computer'.");
            _progress.Message(id: "WifiInstructions2",
                              message: "You can do this on as many devices as you like. Make sure each device is connected to the same network as this computer.");
        }