代码之家  ›  专栏  ›  技术社区  ›  Lucas

Rails应用程序未通过ActionCable显示通知

  •  0
  • Lucas  · 技术社区  · 7 年前

    我有一个todo list rails应用程序,允许一个用户将其他用户的公共列表标记为他们的收藏夹。这里的目标是:当列表所有者创建新的待办事项时,将同一列表标记为其收藏夹的用户应实时收到通知,而无需刷新页面。

    应用程序/资产/javascripts/频道/通知。js公司

    App.notifications = App.cable.subscriptions.create("NotificationsChannel", {
          connected: function() {
            // Called when the subscription is ready for use on the server
          },
    
          disconnected: function() {
            // Called when the subscription has been terminated by the server
          },
    
          received: function(data) {
            // Called when there's incoming data on the websocket for this channel
            $("#notifications").prepend(data.html);
          }
    

    });

    我的div-in 应用程序/视图/布局/应用程序。html。雇员再培训局

          <body>
              <div class="container">
              <div id="notifications">
    
              </div>
              <header>
                <div class="header_inner">
                  <nav style="text-align: right;">
                    <% if user_signed_in? %>
                      <%= link_to 'New Todo List', new_todo_list_path %> |
                      <%= link_to "Sign out", destroy_user_session_path, method: :delete %>
                    <% else %>
                      <%= link_to "Log in", new_user_session_path %>
                    <% end %>
                  </nav>
                </div>
              </header>
              <%= yield %>
            </div>
          </body>
    

    应用程序/型号/通知。rb型

    class Notification < ApplicationRecord
      after_create_commit { NotificationRelayJob.perform_later(self) }
    
      belongs_to :user
      belongs_to :recipient, class_name: "User"
      belongs_to :notifiable, polymorphic: true
    end
    

    应用程序/型号/待办事项列表。rb型

    class TodoList < ApplicationRecord
      belongs_to :user
      has_many :todo_items, dependent: :destroy
    
      has_many :favorites
      has_many :users, through: :favorites
    
      validates :title, presence: true
      validates :description, length: { maximum: 50 }
    
      def public?
        self.public
      end
    end
    

    已创建应用程序/视图/通知/待办事项列表/\u。html。雇员再培训局

    <div><%= notification.user.email %> <%= notification.action %> new item!</div>
    

    应用程序/频道/通知\u频道。rb型

    class NotificationsChannel < ApplicationCable::Channel
      def subscribed
        stream_from "notifications:#{current_user.id}"
      end
    
      def unsubscribed
        stop_all_streams
      end
    end
    

    app/jobs/notification\u relay\u作业。rb型

      class NotificationRelayJob < ApplicationJob
      queue_as :default
    
      def perform(notification)
        html = ApplicationController.render partial: "notifications/#{notification.notifiable_type.underscore.pluralize}/#{notification.action}", locals: {notification: notification}, formats: [:html]
        ActionCable.server.broadcast "notifications:#{notification.current_user}", html: html
      end
    

    应用程序/控制器/todo\u项目\u控制器。rb型

    class TodoItemsController < ApplicationController
      before_action :set_todo_list
      before_action :set_todo_item, except: [:create]
    
      def create
        @todo_item = @todo_list.todo_items.new(todo_item_params)
        if @todo_item.save
          @todo_list.users.each do |user|
            @noti = Notification.create(recipient: user, user: User.last, action: "create", notifiable: @todo_list)
          end
          redirect_to @todo_list, notice: 'Todo item added!'
        else
          redirect_to @todo_list, alert: 'Please some content in the new todo item'
        end
      end
      ...
    

    发展日志

    web_1  | Finished "/cable/" [WebSocket] for 172.23.0.1 at 2018-04-17 00:58:28 +0000
    web_1  | NotificationsChannel stopped streaming from notifications:2
    web_1  | Started GET "/cable" for 172.23.0.1 at 2018-04-17 00:58:28 +0000
    web_1  | Cannot render console from 172.23.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
    web_1  | Started GET "/cable/" [WebSocket] for 172.23.0.1 at 2018-04-17 00:58:28 +0000
    web_1  | Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
    web_1  |   User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 2], ["LIMIT", 1]]
    web_1  | Registered connection (Z2lkOi8vZmFudGFzdGljLXN5c3RlbS9Vc2VyLzI)
    web_1  | NotificationsChannel is transmitting the subscription confirmation
    web_1  | NotificationsChannel is streaming from notifications:2
    web_1  | Started POST "/todo_lists/3/todo_items" for 172.23.0.1 at 2018-04-17 00:58:31 +0000
    web_1  | Cannot render console from 172.23.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
    web_1  | Processing by TodoItemsController#create as HTML
    web_1  |   Parameters: {"utf8"=>"✓", "authenticity_token"=>"WfKWJNbd0HiPj64/51vXsj7O/mJ7nF/U6tvwP5OQMsTLE0cgUQHXYq7D08bB3RUxuxqVTvcD6uGzWcNJqkxGQA==", "todo_item"=>{"content"=>"asd"}, "commit"=>"Create Todo item", "todo_list_id"=>"3"}
    web_1  |   TodoList Load (0.3ms)  SELECT  "todo_lists".* FROM "todo_lists" WHERE "todo_lists"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
    web_1  |    (0.1ms)  begin transaction
    web_1  |   SQL (2.2ms)  INSERT INTO "todo_items" ("content", "todo_list_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["content", "asd"], ["todo_list_id", 3], ["created_at", "2018-04-17 00:58:31.708390"], ["updated_at", "2018-04-17 00:58:31.708390"]]
    web_1  |    (157.7ms)  commit transaction
    web_1  |   User Load (0.4ms)  SELECT "users".* FROM "users" INNER JOIN "favorites" ON "users"."id" = "favorites"."user_id" WHERE "favorites"."todo_list_id" = ?  [["todo_list_id", 3]]
    web_1  |   User Load (0.3ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ?  [["LIMIT", 1]]
    web_1  |    (0.1ms)  begin transaction
    web_1  |   SQL (1.5ms)  INSERT INTO "notifications" ("user_id", "recipient_id", "action", "notifiable_type", "notifiable_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?)  [["user_id", 3], ["recipient_id", 1], ["action", "followed"], ["notifiable_type", "TodoList"], ["notifiable_id", 3], ["created_at", "2018-04-17 00:58:31.915523"], ["updated_at", "2018-04-17 00:58:31.915523"]]
    web_1  |    (97.2ms)  commit transaction
    web_1  | [ActiveJob] Enqueued NotificationRelayJob (Job ID: a32e8a9d-d9fd-4a1c-90c1-891c48709b4b) to Async(default) with arguments: #<GlobalID:0x00007f651054f610 @uri=#<URI::GID gid://fantastic-system/Notification/72>>
    web_1  | Redirected to http://localhost:3000/todo_lists/3
    web_1  |   Notification Load (0.6ms)  SELECT  "notifications".* FROM "notifications" WHERE "notifications"."id" = ? LIMIT ?  [["id", 72], ["LIMIT", 1]]
    web_1  | Completed 302 Found in 359ms (ActiveRecord: 261.1ms)
    web_1  | 
    web_1  | 
    web_1  | [ActiveJob] [NotificationRelayJob] [a32e8a9d-d9fd-4a1c-90c1-891c48709b4b] Performing NotificationRelayJob (Job ID: a32e8a9d-d9fd-4a1c-90c1-891c48709b4b) from Async(default) with arguments: #<GlobalID:0x00007f64cc04ab18 @uri=#<URI::GID gid://fantastic-system/Notification/72>>
    web_1  | [ActiveJob] [NotificationRelayJob] [a32e8a9d-d9fd-4a1c-90c1-891c48709b4b]   User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
    web_1  | [ActiveJob] [NotificationRelayJob] [a32e8a9d-d9fd-4a1c-90c1-891c48709b4b]   Rendered notifications/todo_lists/_followed.html.erb (4.9ms)
    web_1  | [ActiveJob] [NotificationRelayJob] [a32e8a9d-d9fd-4a1c-90c1-891c48709b4b] [ActionCable] Broadcasting to notifications:3: {:html=>"<div>a@a.com.br followed you!</div>\n"}
    web_1  | [ActiveJob] [NotificationRelayJob] [a32e8a9d-d9fd-4a1c-90c1-891c48709b4b] Performed NotificationRelayJob (Job ID: a32e8a9d-d9fd-4a1c-90c1-891c48709b4b) from Async(default) in 7.58ms
    web_1  | Started GET "/todo_lists/3" for 172.23.0.1 at 2018-04-17 00:58:32 +0000
    web_1  | Cannot render console from 172.23.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
    web_1  | Processing by TodoListsController#show as HTML
    web_1  |   Parameters: {"id"=>"3"}
    web_1  |   TodoList Load (0.2ms)  SELECT  "todo_lists".* FROM "todo_lists" WHERE "todo_lists"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
    web_1  |   Rendering todo_lists/show.html.erb within layouts/application
    web_1  |   TodoItem Load (0.2ms)  SELECT "todo_items".* FROM "todo_items" WHERE "todo_items"."todo_list_id" = ?  [["todo_list_id", 3]]
    web_1  |   User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
    web_1  |   User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 2], ["LIMIT", 1]]
    web_1  |   Rendered collection of todo_items/_todo_item.html.erb [4 times] (7.3ms)
    web_1  |   Rendered todo_items/_form.html.erb (2.8ms)
    web_1  |   Rendered todo_lists/show.html.erb within layouts/application (16.8ms)
    web_1  | Completed 200 OK in 47ms (Views: 44.4ms | ActiveRecord: 1.1ms)
    web_1  | 
    web_1  | 
    web_1  | Finished "/cable/" [WebSocket] for 172.23.0.1 at 2018-04-17 00:58:32 +0000
    web_1  | NotificationsChannel stopped streaming from notifications:2
    web_1  | Started GET "/cable" for 172.23.0.1 at 2018-04-17 00:58:32 +0000
    web_1  | Cannot render console from 172.23.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
    web_1  | Started GET "/cable/" [WebSocket] for 172.23.0.1 at 2018-04-17 00:58:32 +0000
    web_1  | Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
    web_1  |   User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 2], ["LIMIT", 1]]
    web_1  | Registered connection (Z2lkOi8vZmFudGFzdGljLXN5c3RlbS9Vc2VyLzI)
    web_1  | NotificationsChannel is transmitting the subscription confirmation
    web_1  | NotificationsChannel is streaming from notifications:2
    

    我可以通过“@todo\u list.users”(将收到通知)查看所有喜欢列表的用户,控制台说NotificationChannel正在传输和流式处理,但当我创建新的todo项目时,什么都没有发生。我已经搜索了一段时间,但似乎我对ActionCable不是很了解:(。

    非常感谢您的帮助。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Léo Rocha    7 年前

    最初,问题是您向谁发送通知。您特别注意通知。当前的\u用户,必须将其发送到通知。收件人\u id

    在里面 app/jobs/notification\u relay\u作业。rb型

    更改代码

    ActionCable.server.broadcast "notifications:#{notification.current_user}", html: html
    

    ActionCable.server.broadcast "notifications:#{notification.recipient_id}", html: html
    

    完成此操作后,在发件人和收件人用户中登录,创建通知并再次测试。