-
-
Save jevin/414dcdb1b1fe6d5e48c2e9dc53fbc931 to your computer and use it in GitHub Desktop.
# config/routes.rb | |
Rails.application.routes.draw do | |
mount ActionCable.server, at: '/cable' | |
end | |
# app/channels/chat_channel.rb | |
class ChatChannel < ApplicationCable::Channel | |
def subscribed | |
stream_from "chat_channel" | |
end | |
def unsubscribed | |
end | |
def speak(data) | |
ActionCable.server.broadcast("chat_channel", message: "#{data["message"]}") | |
end | |
end |
# Goes inside componentDidMount() in any screen | |
this.ws = new WebSocket('ws://0.0.0.0:3000/cable'); | |
this.channel_name = 'ChatChannel'; | |
this._handleMessage = (data) => { | |
this.setState({ | |
messages: this.state.messages.concat([data.message.message]) | |
}) | |
} | |
this.ws.onopen = () => { | |
const msg = { | |
command: 'subscribe', | |
identifier: JSON.stringify({ | |
channel: this.channel_name, | |
}), | |
}; | |
this.ws.send(JSON.stringify(msg)); | |
}; | |
this.ws.onmessage = e => { | |
var data = JSON.parse(e.data); | |
if (data.identifier != undefined) { | |
data.identifier = JSON.parse(data.identifier) | |
} | |
if (data.type == "welcome" || data.type == "ping" || data.type == "confirm_subscription") { | |
return; | |
} | |
if (data.identifier.channel == this.channel_name) { | |
this._handleMessage(data) | |
return; | |
} | |
}; | |
this.ws.onerror = e => { | |
console.log("ERROR: " + e.message); | |
}; | |
this.ws.onclose = e => { | |
console.log("CONNECTION CLOSED: " + e.code + " " + e.reason); | |
}; | |
this.ws.sendmessage = data => { | |
const msg = { | |
command: 'message', | |
identifier: JSON.stringify({ | |
channel: 'ChatChannel', | |
}), | |
data: JSON.stringify(data) | |
}; | |
this.ws.send(JSON.stringify(msg)); | |
} | |
# Somewhere in the code | |
_sendMessage = (message) => { | |
this.ws.sendmessage({ | |
action: 'speak', | |
message: message, | |
}); | |
} | |
<TouchableOpacity onPress={() => this._sendMessage("Hello world!)}> | |
<Text> | |
Send message | |
</Text> | |
</TouchableOpacity> |
Thanks! The whole code needs a refresh. I think you’re right in your this.ws.close() placement.
Thanks! The whole code needs a refresh. I think you’re right in your this.ws.close() placement.
Thanks! The whole code needs a refresh. I think you’re right in your this.ws.close() placement.
Is there anything else you need to do on the rails side to channel.rb or connection.rb?
I guess our ChatChannel inherits from Channel < ActionCable::Channel::Base so that sort of takes care of it. I like this approach instaed of using the action cable npm package on the front end which seems a bit more work than its worth. cheers!
Yeah I don’t think anything else is needed. The idea was to make this Gist as simple as possible.
Like you said, that’s why I’m not using any npm package.
Would you set a this.ws.close() inside your componentWillUnmount() and send a message to 'unsubscribe' in the cable?