Rails Actioncable сообщение приходит до того, как документ готов - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь использовать ActionCable и веб-сокеты для реализации страницы, где сервер выполняет какие-то действия через задание Sidekiq и отправляет сообщения обратно в браузер пользователя, чтобы обновить страницу. Должно быть просто, верно?

Я делаю первую основную вещь c, которая по сути отправляет сообщение в контроллере, и браузер Javascript должен его обработать. Ну, это так, но это так хорошо , прежде чем страница будет загружена / готова. И я пытаюсь выяснить, почему.

Вот упрощенный контроллер:

def create
  some stuff
  render
  ActionCable.server.broadcast "opml_items_channel:#{current_user.id}",
            { message: "Current Status: Found #{@opml_items.length} items" }
end

А вот Javascript для канала:

App.opmlitems = App.cable.subscriptions.create("OpmlItemsChannel", {
  connected: function() {
    //console.log("connected");
  },

  disconnected: function() {
    //console.log("disconnected");
  },

  received: function(data) {
    //console.log("recieved");
    console.log(data['message']);
    // wait for document ready otherwise the message comes before the
    // page is rendered
    $( document ).ready(function() {
      console.log("doing the thing")
      console.log(document.querySelector('#status-p'));
      if ( document.querySelector('#status-p') != null ) {
        document.querySelector('#status-p').innerText = data['message'];
      }
    });
  }
});

Это полностью работает в том, что консоль регистрирует «что-то» , но делает это даже до полной загрузки страницы браузером, несмотря на document.ready. Глядя на консоль браузера, я вижу:

Current Status: Found 11 items
doing the thing
null
Navigated to http://localhost:3000/opml_items

null потому, что #status-p еще не существует во время вызова функции received.

В журнале рельсов я вижу:

Started POST "/opml_items" for 127.0.0.1 at 2020-04-06 01:14:33 +0000
Processing by OpmlItemsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"7UQye0uFoThYZvoP8cxW/Wbz+QEi6IR5TXYoJFQeD1cXl5h6SZRYDpAyRIX7EYoQu6mGO/r76XgGZRap2le1hQ==", "upload"=>{"opml_file"=>#<ActionDispatch::Http::UploadedFile:0x00007f0bfeeac3b8 @tempfile=#<Tempfile:/tmp/RackMultipart20200406-358-1ekfo8l.opml>, @original_filename="too-many.opml", @content_type="text/x-opml+xml", @headers="Content-Disposition: form-data; name=\"upload[opml_file]\"; filename=\"too-many.opml\"\r\nContent-Type: text/x-opml+xml\r\n">}, "commit"=>"Import OPML"}
blah blah standard rails stuff
[ActionCable] Broadcasting to opml_items_channel:1: {:message=>"Current Status: Found 11 items"}
Completed 200 OK in 713ms (Views: 612.4ms | ActiveRecord: 28.8ms | Elasticsearch: 0.0ms)

Итак, это долгий путь вопроса - как я могу заставить сообщения ActionCable полностью приходить после рендеринга страницы? Вы можете видеть мой render, который указывает, что порядок ( в журнале ) указывает на то, что сообщение ActionCable приходит в самом конце. Тем не менее, что касается браузера, он все еще, кажется, не соблюдает ready.

WDYT?

...