2

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

https://github.com/kwent/actioncable_stream_dart

https://pub.dev/packages/action_cable

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

4

1 回答 1

0

I am using action_cable

I hope the following code can help you

Flutter App

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(() {});
  }
}

Back-end 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

于 2021-05-09T00:58:33.430 回答