无法从 React 前端的 ActionCable 访问数据
Cannot access data from ActionCable on React front-end
我正在尝试使用 actioncable 从 rails 后端广播属于某个游戏的消息。
在我的messages_controller中:
def create
@game = Game.find(message_params[:game_id])
@message = Message.new(message_params)
if @message.save
serialized_data = ActiveModelSerializers::Adapter::Json.new(
MessageSerializer.new(@message)
).serializable_hash
MessagesChannel.broadcast_to @game, serialized_data
head :ok
end
end
在我的 messages_channel:
def subscribed
@game = Game.find(params[:id][:game_id])
stream_from @game
end
在前端,我正在使用这个文件:
import ActionCable from 'actioncable';
import { CABLE } from "../constants";
export default function MessagesSubscription(
game_id,
{ onUpdate = () => {} } = {}
) {
// 2. Define our constructor
this.cable = ActionCable.createConsumer(CABLE);
// this.channel;
this.game_id = game_id;
this.onUpdate = onUpdate;
// 3. Define the function we will call to subscribe to our channel
this.subscribe = () => {
console.log("subscribed")
this.channel = this.cable.subscriptions.create(
{ channel: 'MessagesChannel', id: this.game_id },
{
connected: this.connected,
disconnected: this.disconnected,
received: this.received,
rejected: this.rejected,
}
);
};
// 4. Define our default ActionCable callbacks.
this.received = (data) => {
console.log(`Received Data: ${data}`);
this.onUpdate(data);
};
this.connected = () => {
console.log(`this.connected`);
};
this.disconnected = () => {
console.warn(`this.disconnected.`);
};
this.rejected = () => {
console.warn('I was rejected! :(');
};
}
问题是在客户端我可以点击连接、断开和拒绝,但我不能点击接收。
当 运行 服务器和客户端时,如果我查看终端中的 rails 后端,我会看到以下内容:
MessagesChannel is transmitting the subscription confirmation
MessagesChannel is streaming from # Started
GET "/api/v1/cable" for 127.0.0.1 at 2019-03-21 10:29:09 -0400 Started
GET "/api/v1/cable/" [WebSocket] for 127.0.0.1 at 2019-03-21 10:29:09
-0400 Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket) Could not execute
command from ({"command"=>"subscribe",
"identifier"=>"{\"channel\":\"MessagesChannel\",\"game_id\":\"15\"}"})
[NoMethodError - undefined method []' for nil:NilClass]:
/Users/flatironschool/Development/code/Flatiron/mod5/project/deep_forest_api/app/channels/messages_channel.rb:3:in
subscribed' |
/Users/flatironschool/.rvm/gems/ruby-2.6.1/gems/actioncable-5.2.2.1/lib/action_cable/channel/base.rb:179:in block in subscribe_to_channel' |
/Users/flatironschool/.rvm/gems/ruby-2.6.1/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:109:in
block in run_callbacks' |
/Users/flatironschool/.rvm/gems/ruby-2.6.1/gems/activesupport-5.2.2.1/lib/active_support/execution_wrapper.rb:83:in
wrap' |
/Users/flatironschool/.rvm/gems/ruby-2.6.1/gems/actioncable-5.2.2.1/lib/action_cable/engine.rb:68:in
block (3 levels) in '
我在学校得到了 TCF 的帮助。
在我的消息频道中,我将其更改为:
def subscribed
@game = Game.find(params[:id][:game_id])
stream_for @game
end
因此,stream_for 而不是 stream_from。
此外,我还切换到使用 npm 包 react-actioncable-provider。
我的客户端 javascript 在 React 中,看起来像这样:
import { ActionCable } from 'react-actioncable-provider';
import React, { Component, Fragment } from 'react';
import { CABLE, AUTH_HEADERS } from '../constants';
import { connect } from 'react-redux';
import Message from '../components/Message';
class Cable extends Component {
render () {
console.log("Cable.js")
return (
<Fragment>
<ActionCable
key={this.props.game_id}
channel={{ channel: "MessagesChannel", game_id: this.props.game_id }}
onReceived={(data) => console.log("handleReceived: ", data)}
/>
</Fragment>
)
}
}
const mapStateToProps = state => {
return { state }
}
const mapDispatchToProps = dispatch => {
return {
getMessages: data => dispatch({ type: "LOAD_MSGS", payload: data })
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Cable);
我现在可以接收来自 ActionCable 的回复。
我正在尝试使用 actioncable 从 rails 后端广播属于某个游戏的消息。
在我的messages_controller中:
def create
@game = Game.find(message_params[:game_id])
@message = Message.new(message_params)
if @message.save
serialized_data = ActiveModelSerializers::Adapter::Json.new(
MessageSerializer.new(@message)
).serializable_hash
MessagesChannel.broadcast_to @game, serialized_data
head :ok
end
end
在我的 messages_channel:
def subscribed
@game = Game.find(params[:id][:game_id])
stream_from @game
end
在前端,我正在使用这个文件:
import ActionCable from 'actioncable';
import { CABLE } from "../constants";
export default function MessagesSubscription(
game_id,
{ onUpdate = () => {} } = {}
) {
// 2. Define our constructor
this.cable = ActionCable.createConsumer(CABLE);
// this.channel;
this.game_id = game_id;
this.onUpdate = onUpdate;
// 3. Define the function we will call to subscribe to our channel
this.subscribe = () => {
console.log("subscribed")
this.channel = this.cable.subscriptions.create(
{ channel: 'MessagesChannel', id: this.game_id },
{
connected: this.connected,
disconnected: this.disconnected,
received: this.received,
rejected: this.rejected,
}
);
};
// 4. Define our default ActionCable callbacks.
this.received = (data) => {
console.log(`Received Data: ${data}`);
this.onUpdate(data);
};
this.connected = () => {
console.log(`this.connected`);
};
this.disconnected = () => {
console.warn(`this.disconnected.`);
};
this.rejected = () => {
console.warn('I was rejected! :(');
};
}
问题是在客户端我可以点击连接、断开和拒绝,但我不能点击接收。
当 运行 服务器和客户端时,如果我查看终端中的 rails 后端,我会看到以下内容:
MessagesChannel is transmitting the subscription confirmation MessagesChannel is streaming from # Started GET "/api/v1/cable" for 127.0.0.1 at 2019-03-21 10:29:09 -0400 Started GET "/api/v1/cable/" [WebSocket] for 127.0.0.1 at 2019-03-21 10:29:09 -0400 Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket) Could not execute command from ({"command"=>"subscribe", "identifier"=>"{\"channel\":\"MessagesChannel\",\"game_id\":\"15\"}"}) [NoMethodError - undefined method
[]' for nil:NilClass]: /Users/flatironschool/Development/code/Flatiron/mod5/project/deep_forest_api/app/channels/messages_channel.rb:3:in
subscribed' | /Users/flatironschool/.rvm/gems/ruby-2.6.1/gems/actioncable-5.2.2.1/lib/action_cable/channel/base.rb:179:inblock in subscribe_to_channel' | /Users/flatironschool/.rvm/gems/ruby-2.6.1/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:109:in
block in run_callbacks' | /Users/flatironschool/.rvm/gems/ruby-2.6.1/gems/activesupport-5.2.2.1/lib/active_support/execution_wrapper.rb:83:inwrap' | /Users/flatironschool/.rvm/gems/ruby-2.6.1/gems/actioncable-5.2.2.1/lib/action_cable/engine.rb:68:in
block (3 levels) in '
我在学校得到了 TCF 的帮助。
在我的消息频道中,我将其更改为:
def subscribed
@game = Game.find(params[:id][:game_id])
stream_for @game
end
因此,stream_for 而不是 stream_from。
此外,我还切换到使用 npm 包 react-actioncable-provider。
我的客户端 javascript 在 React 中,看起来像这样:
import { ActionCable } from 'react-actioncable-provider';
import React, { Component, Fragment } from 'react';
import { CABLE, AUTH_HEADERS } from '../constants';
import { connect } from 'react-redux';
import Message from '../components/Message';
class Cable extends Component {
render () {
console.log("Cable.js")
return (
<Fragment>
<ActionCable
key={this.props.game_id}
channel={{ channel: "MessagesChannel", game_id: this.props.game_id }}
onReceived={(data) => console.log("handleReceived: ", data)}
/>
</Fragment>
)
}
}
const mapStateToProps = state => {
return { state }
}
const mapDispatchToProps = dispatch => {
return {
getMessages: data => dispatch({ type: "LOAD_MSGS", payload: data })
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Cable);
我现在可以接收来自 ActionCable 的回复。