gosugod
@gosugod
Фулл-стэк на Реакте и Рельсах :)

Почему React клиент не получает данные через ActionCable?

Добрый день. Пытаюсь подключить React к ActionCable.
При отправке POST запроса на сервер я вижу такие вот сообщения:
Network cable log

5ea14abd7d161868752400.png

{"type":"welcome"}
{"command":"subscribe","identifier":"{\"channel\":\"BoardsChannel\"}"}
{"identifier":"{\"channel\":\"BoardsChannel\"}","type":"confirm_subscription"}
{"type":"ping","message":1587628697}
{"command":"message","identifier":"{\"channel\":\"BoardsChannel\"}","data":"{\"id\":104,\"title\":\"Sample list\",\"board_id\":30,\"created_at\":\"2020-04-23T07:58:18.738Z\",\"updated_at\":\"2020-04-23T07:58:18.738Z\"}"}


При этом если открыть вторую вкладку, никакие данные не приходят, хотя клиент подписывается на канал.

Boards channel

class BoardsChannel < ApplicationCable::Channel
  def subscribed
    stream_for "boards_channel"
  end

  def unsubscribed
    stop_all_streams
  end

  def receive(data)
    ActionCable.server.broadcast "boards_channel", data
  end
end



Для трёх моделей у меня лишь один канал. В чём проблема? Почему канал не стримит данные?
Ниже контейнер обрабатывающий логику и подключающий клиент к вебсокету:

BoardsContainer

import React from "react";
import axios from "axios";
import update from "immutability-helper";
import ActionCable from "actioncable";

import { API_ROOT, API_WS_ROOT } from "../../../constants";
import Board from "./components/Board";

export default class BoardContainer extends React.Component {
  constructor() {
    super();

    this.state = {
      lists: [],
    };

    this.createList = this.createList.bind(this);
    this.handleReceiveNewList = this.handleReceiveNewList.bind(this);

    this.goBack = this.goBack.bind(this);
    this.deleteList = this.deleteList.bind(this);
  }

  goBack() {
    window.location.href = "/";
  }

  handleReceiveNewList = (data) => {
    console.log('data:', data);
    this.setState({
      lists: [...this.state.lists, data],
    });
  };

  componentDidMount = () => {
    window.fetch(`${API_ROOT}/lists`).then((data) => {
      data.json().then((res) => {
        this.setState({ lists: res.lists });
      });
    });

    const cable = ActionCable.createConsumer(API_WS_ROOT);

    this.sub = cable.subscriptions.create("BoardsChannel", {
      received: (data) => {
        this.handleReceiveNewList(data);
      },
      connected: () => {
        console.log('connected');
      }
    });
  };

  createList() {
    axios
      .post(`${API_ROOT}/lists`, {
        list: {
          board_id: this.props.board_id,
          title: "Sample list",
        },
      })
      .then((response) => {
        const list = response.data;
        this.sub.send(list);
        const lists = this.state.lists.concat(response.data);
        this.setState({ lists: lists });
      });
  }

  deleteList = (id) => {
    axios
      .delete(`${API_ROOT}/lists/${id}`)
      .then(() => {
        const listIndex = this.state.lists.findIndex((x) => x.id === id);
        const lists = update(this.state.lists, { $splice: [[listIndex, 1]] });
        this.setState({ lists: lists });
      })
      .catch((error) => console.error(error));
  };

  render() {
    return (
      <div>
        <Board
          goBack={this.goBack}
          createList={this.createList}
          allLists={this.state.lists}
          board_id={this.props.board_id}
          deleteList={this.deleteList}
          handleReceivedLists={this.handleReceivedLists}
        />
      </div>
    );
  }
}



Create ListController'a :

def create

def create
      @list = List.new(list_params)

      @board = Board.find(list_params[:board_id])

      if @list.save
        serialized_data = ActiveModelSerializers::Adapter::Json.new(
          ListSerializer.new(@list)
        ).serializable_hash
        ActionCable.server.broadcast "boards_channel", serialized_data
        render json: @list.to_json, status: :ok
      end
    end



Что тут не так и почему клиенты не получают данные, хотя подписаны на канал?
  • Вопрос задан
  • 67 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы