react-actioncable-provider icon indicating copy to clipboard operation
react-actioncable-provider copied to clipboard

onReceived is never called

Open patrickemuller opened this issue 7 years ago • 7 comments

What I'm trying to do?

I'm trying to use the backend with some background jobs to notify user about the "processing" time of some CSV file. For that, I'm notifying the frontend about the processed rows of the file, but, onReceived function is never called. What I'm doing wrong?

Backend

(this is working, tested manually)

# frozen_string_literal: true

class ImportedBatchChannel < ApplicationCable::Channel
  def subscribed
    stream_for ImportedBatch.find(params[:room])
  end

  def receive(data)
    puts '*****************************'
    puts data
    puts '*****************************'
  end
end

Frontend

(this is not working, OnReceived is never called)

App.js (REACT_APP_WS_URL is localhost:3001/cable for development)

<ActionCableProvider url={process.env.REACT_APP_WS_URL}>
  <MuiThemeProvider theme={theme}>
    <CssBaseline />
    <Navbar />
    <Router />
    <Footer />
  </MuiThemeProvider>
</ActionCableProvider>

ProgressBar.js

import React, { Component, Fragment } from 'react'
import { ActionCable } from 'react-actioncable-provider'
import LinearProgress from '@material-ui/core/LinearProgress'

export default class extends Component {
  state = {
    total: this.props.total,
    processed: this.props.processed,
  }

  onReceived(data) {
    console.log('Recebi', data)
    this.setState({
      total: data.totalRows,
      processed: data.processedRows,
    })
  }

  sendMessage = () => {
    this.refs.ImportedBatchChannel.perform('receive', { message: 'olha essa mensagem' })
  }

  render() {
    return (
      <Fragment>
        <ActionCable
          ref={'ImportedBatchChannel'}
          channel={{
            channel: 'ImportedBatchChannel',
            room: this.props.batchId,
          }}
          onReceived={this.onReceived}
        />

        <div className={this.props.classes.progressBar}>
          <LinearProgress
            variant="determinate"
            value={(this.state.processed / this.state.total) * 100}
          />
        </div>
        <button onClick={this.sendMessage}>Mandar Mensagem</button>
      </Fragment>
    )
  }
}

patrickemuller avatar Nov 16 '18 16:11 patrickemuller

Same problem

wh1le avatar Nov 28 '18 20:11 wh1le

@nmiloserdov check if you're using "async" on backend and change to "redis". Worked for me. but yeah, I think its bugged anyway.

patrickemuller avatar Nov 28 '18 21:11 patrickemuller

@patrickemuller I use 'redis' by default. What do you mean by using "async" on the backend?

wh1le avatar Nov 28 '18 21:11 wh1le

There is and option on cable.yml that solved my problem, using redis instead os 'async' adapter. you're using redis already, so there is nothing to change.

patrickemuller avatar Nov 28 '18 22:11 patrickemuller

@patrickemuller I found the problem. ActilnCable rejected my connection because of the custom validation of the user id. onConnected and onDisconnected callbacks helped me to figured this out.

wh1le avatar Nov 29 '18 10:11 wh1le

@cpunion you just need to describe these methods on documentation :)

wh1le avatar Nov 29 '18 10:11 wh1le

@nmiloserdov @cpunion Also, I added .bind for those methods on my frontend code. I think that was missed from the beginning.

patrickemuller avatar Nov 30 '18 18:11 patrickemuller