【问题标题】:How to connect Flutter to Rails 6.1 Action Cable Websocket?如何将 Flutter 连接到 Rails 6.1 Action Cable Websocket?
【发布时间】:2021-05-29 05:58:02
【问题描述】:

我正在尝试使用 action_cable_streamaction_cable 将 Flutter 连接到 Rails 6.1 Web 应用程序

https://github.com/kwent/actioncable_stream_dart

https://pub.dev/packages/action_cable

但是,我无法在生产或开发中建立连接。有没有人能够为 Rails 6.1 实现这两个包?

【问题讨论】:

    标签: ruby-on-rails flutter websocket actioncable ruby-on-rails-6.1


    【解决方案1】:

    我正在使用action_cable

    希望下面的代码可以帮助到你

    Flutter 应用

    class InvestigacionPage extends StatefulWidget {
      final Investigacion investigacion;
      InvestigacionPage(this.investigacion);
    
      @override
      _InvestigacionPageState createState() => _InvestigacionPageState();
    }
    
    class _InvestigacionPageState extends State<InvestigacionPage> {
      final String _channel = 'Investigacion';
      final String _action_cable_url = 'wss://my.domain/cable';
      bool isConnected = false;
      bool isSubscribed = false;
      bool isSended = false;
      String stateText = 'Cargando...';
      ActionCable actionCable;
      Investigacion investigacion;
    
      @override
      void initState() {
        super.initState();
        this.investigacion = widget.investigacion;
      }
    
      @override
      void dispose() {
        super.dispose();
        actionCable.disconnect();
      }
    
      @override
      Widget build(BuildContext context) {
        if (isConnected) {
          if (isSubscribed) {
            if (!isSended) enviar();
          } else {
            subscribeChanel();
          }
        } else {
          conectarCanal(_action_cable_url);
        }
    
        return Scaffold(
          appBar: AppBar(
            title: Text('Investigación ${investigacion.id}'),
          ),
          body: Column(
            children: [
              Container(
                width: double.infinity,
                child: Card(
                  margin: EdgeInsets.all(15.0),
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Column(
                      children: [
                        Text(investigacion.identificador),
                      ],
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    
      void conectarCanal(String url) async {
        actionCable = ActionCable.Connect(url, headers: {
          "Authorization": await AuthService.getToken(),
        }, onConnected: () {
          stateText = 'Conectado';
          setState(() {
            isConnected = true;
          });
        }, onConnectionLost: () {
          stateText = 'Conección Perdida';
          setState(() {
            isConnected = false;
            isSended = false;
          });
        }, onCannotConnect: () {
          stateText = 'No puede conectarse';
          actionCable.disconnect();
          setState(() {
            isConnected = false;
            isSended = false;
          });
        });
      }
    
      void subscribeChanel() {
        actionCable.subscribe("Investigacion",
            channelParams: {"id": investigacion.id}, onSubscribed: () {
          print('confirm suscription');
          stateText = 'Suscripción a investigación';
          setState(() {
            isSubscribed = true;
          });
        }, // `confirm_subscription` received
            onDisconnected: () {
          stateText = 'Conexión perdida';
          setState(() {
            isSubscribed = false;
            isSended = false;
          });
        }, // `disconnect` received
            onMessage: (Map message) {
          stateText = 'En linea';
          print('mensaje => $message');
          this.investigacion = Investigacion.fromJson(message);
    
          setState(() {});
        } // any other message received
            );
      }
    
      void enviar() {
        actionCable.performAction("Investigacion",
            action: "receive",
            channelParams: {"id": investigacion.id},
            actionParams: {"message": "INVESTIGACION! ?"});
        isSended = true;
        setState(() {});
      }
    }
    
    

    后端 Rails

    class InvestigacionChannel < ApplicationCable::Channel
      def subscribed
        stream_from "investigacion_#{params[:id]}"
      end
    
      def receive(data)
        puts "receive datos => #{params.inspect}"
        investigacion = current_user.investigaciones.find(params[:id])
        ActionCable.server.broadcast "investigacion_#{params[:id]}", investigacion
      rescue => e
        puts "Presenta un error en receive de socket"
        puts e
      end
    end
    
    

    【讨论】:

      猜你喜欢
      • 2018-03-10
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      • 2017-08-23
      • 2018-03-28
      • 2020-06-29
      • 2021-07-09
      • 1970-01-01
      相关资源
      最近更新 更多