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

使用React前端中的Rails ActionCable对象。

  •  0
  • mayorsanmayor  · 技术社区  · 6 年前

    我有一个 appointment model,我想在每次创建或更新约会时在react中将广播发送到前端应用程序。这是我的模型代码。

    class appointment<applicationrecord
    属于:导师,班级名称:'user'
    属于:学生,班级名称:'user'
    
    创建后:预约通知
    更新后:预约通知
    
    def预约\通知
    通知。创建(
    来自:学生,
    导师:
    name::student_create_appointment,这里您可以检测到任何类型的
    模型::约会
    )
    结束
    结束
    < /代码> 
    
    

    notificationmodel and table to save the history of all notifications

    类通知<applicationrecord
    
    属于\u到:从,类\u名称:'user',外部\u密钥::从\u id
    属于\u到:to,类\u名称:'user',外部\u键::到\u id
    
    在“创建:设置”之前
    
    创建后:推送通知
    
    def设置
    self.seen=错误
    结束
    
    DEF推送通知
    如果发送给.user_push_notification.response_?(名称)&&
    收件人.用户推送通知.发送(名称)
    
    PushNotificationJob.稍后执行(
    来自:
    去,去,
    消息:消息(:push),
    姓名:姓名,
    创建时间:创建时间:iso8601
    )
    结束
    结束
    
    
    def消息(gate_scope)
    #如果我们在翻译中嵌套了YML,gate_scope可以是“sms”、“push”或“email.body”
    I18N.
    “通知。型号。名称。门范围”,
    来自:
    去,去,
    创建时间:创建时间
    )
    结束
    结束
    

    我创建了一个notificationChannelto look like so:。

    类通知频道<applicationCable::channel
    订阅费
    来自“通知频道:当前用户.id”
    结束
    
    已取消订阅定义
    停止所有流
    结束
    结束
    < /代码> 
    
    

    和一个pushNotificationJob看起来像这样:

    class pushNotificationJob<applicationJob
    队列\为:默认值
    
    def执行(从:,到:,消息:,名称:,创建时间:)
    通知频道。广播到(
    去,
    类型:名称,
    来电者:来自
    消息:消息,
    创建时间:创建时间
    )
    结束
    结束
    

    一切都很好,唯一缺少的链接是我在前端向用户广播的部分: 这是到目前为止我在JavaScript方面所拥有的。

    app.notificationChannel=app.cable.subscriptions.create(
    '通知频道',
    {
    已连接:函数()。{
    //当订阅可以在服务器上使用时调用
    console.log('通知通道已连接');
    }
    
    断开连接:函数()。{
    //当服务器终止订阅时调用
    console.log('通知通道已断开连接');
    }
    
    接收:功能(数据){
    //当此通道的WebSocket上有传入数据时调用
    console.log(数据);
    }
    }
    ;
    
    //app.notificationChannel.send(test:“数据”);
    

    我无法在浏览器控制台中打印任何内容,除了“连接”和“断开”中的内容。

    创建约会后,这就是我的终端日志的样子。

    你知道我还缺什么吗?我还需要做什么?

    顺便说一句,我还在路由文件中创建了这些路由URL

    resources:notifications,only::index do
    集合做
    将“seen-all”发布到:“notifications-seen-all”
    结束
    成员做
    帖子:看
    结束
    结束
    < /代码> 
    
    

    最后是我的notificationsController

    模块API 模块V1 类通知控制器<apicontroller 操作前:设置用户 DEF指数 @user.incoming_notifications.page(params[:page]).per(params[:per_page]) 结束 德森塞尔 notification.where(seen:false,to_id:@user.id).update(seen:true) 结束 德芙 @user.incoming_notifications.find_by(id:params[:id])seen! 结束 私有的 用户设置用户 @用户=当前用户 结束 结束 结束 结束 < /代码>

    请指导我如何在浏览器控制台中打印通知,然后通过API在react中使用通知。谢谢。

    class Appointment < ApplicationRecord
      belongs_to :tutor, class_name: 'User'
      belongs_to :student, class_name: 'User'
    
      after_create :appointment_notification 
      after_update :appointment_notification 
    
      def appointment_notification
        Notification.create(
          from: student,
          to: tutor,
          name: :student_create_appointment, # here you can detect any type
          model: :appointment
        )
      end
    end
    

    Notification用于保存所有通知历史记录的模型和表

    class Notification < ApplicationRecord
    
      belongs_to :from, class_name: 'User', foreign_key: :from_id
      belongs_to :to, class_name: 'User', foreign_key: :to_id
    
      before_create :set_seen
    
      after_create :push_notification
    
      def set_seen
        self.seen = false
      end
    
      def push_notification
        if to.user_push_notification.respond_to?(name) &&
           to.user_push_notification.send(name)
    
          PushNotificationJob.perform_later(
            from: from,
            to: to,
            message: message(:push),
            name: name,
            created_at: created_at.iso8601
          )
        end
      end
    
    
      def message(gate_scope)
        # gate_scope can be 'sms' or 'push' or 'email.body' if we have nested yml in translations
        I18n.t(
          "notification.#{model}.#{name}.#{gate_scope}",
          from: from,
          to: to,
          created_at: created_at
        )
      end
    end
    

    我创造了一个NotificationsChannel看起来像这样:

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

    还有一个PushNotificationJob看起来像这样:

    class PushNotificationJob < ApplicationJob
      queue_as :default
    
      def perform(from:, to:, message:, name:, created_at:)
        NotificationsChannel.broadcast_to(
          to,
          type: name,
          caller: from,
          message: message,
          created_at: created_at
        )
      end
    end
    

    一切都很好,唯一缺少的链接是我在前端向用户广播的部分: 这是到目前为止我在JavaScript方面所拥有的。

    App.notificationsChannel = App.cable.subscriptions.create(
      'NotificationsChannel',
      {
        connected: function() {
          // Called when the subscription is ready for use on the server
          console.log('Notification Channel connected.');
        },
    
        disconnected: function() {
          // Called when the subscription has been terminated by the server
          console.log('Notification Channel disconnected.');
        },
    
        received: function(data) {
          // Called when there's incoming data on the websocket for this channel
          console.log(data);
        }
      }
    );
    
    // App.notificationsChannel.send({ test: 'data' });
    

    我无法在浏览器控制台中打印任何内容,除了“连接”和“断开”中的内容。

    创建约会后,这就是我的终端日志的样子。

    enter image description here

    你知道我还缺什么吗?我还需要做什么?

    顺便说一句,我还在路由文件中创建了这些路由URL

    resources :notifications, only: :index do
       collection do
           post 'seen_all', to: "notifications#seen_all"
        end
        member do
           post :seen
        end
    end
    

    最后我的NotificationsController.

    module API
      module V1
        class NotificationsController < ApiController
          before_action :set_user
    
          def index
            @user.incoming_notifications.page(params[:page]).per(params[:per_page])
          end
    
          def seen_all
            Notification.where(seen: false, to_id: @user.id).update(seen: true)
          end
    
          def seen
            @user.incoming_notifications.find_by(id: params[:id]).seen!
          end
    
          private
    
          def set_user
            @user = current_user
          end
        end
      end
    end
    

    请指导我如何在浏览器控制台中打印通知,然后通过API在react中使用通知。谢谢。

    2 回复  |  直到 6 年前
        1
  •  0
  •   Usman Khan    6 年前

    您可以使用下面的教程来完成这项工作。 这很容易实现 Using Action Cable With React 我已经遵循了一些项目的指导方针。

        2
  •  1
  •   Abhishek Kanojia    6 年前

    有关详细信息,请查看延迟的作业日志。 尝试以下操作:

     def perform(from:, to:, message:, name:, created_at:)
        ActionCable.server.broadcast "notification_channel:#{to.id}", { type: type, caller: caller.name, message: message, created_at: created_at }
      end
    

    这里的提示: 使用 after_commit: :do_something, on: [:create, :update] 而不是使用 after_create . 这将确保只有在成功创建约会后才会触发通知。