问题
I am trying to send a heartbeat pong response to a ping in Websocket connections in my project using reactjs front end with the actioncable module and a Rails backend with Action Cable, but I cannot get the backend to recognize a pong response.
I have gotten to the point where, after receiving a ping message through the websocket 'onmessage' listener, and I can get the backend to receive my response but it cannot process the response as a pong to the ping since it appears the backend does not recognize the type or action as such. If I send 'ChatChannel' a response, the below code produces 'ChatChannel#message ...' in the console logs but the connection is closed after 3 pings. I need the backend to recognize the pong message and continue the websocket connection.
After reading pretty much everything available my questions are the following:
- Is a pong request only possible by using websocket frames?
- If 1 is no, what action or type do I use in the pong response for the backend to recognize the response as one for the ping? If yes, why would there be a "onmessage" listener that receives pings then closes the connection if there is no response...???
{action [or type]: ?, data: [ping message body] } Note: The websocket documentation states that the data for the pong needs to be the same as the message body of the ping
The below code produces three console logs below then the connection closes due to non-response: ChatChannel#message "ChatChannel ponged in #message"
Here is my code:
RAILS
app/channel/application_cable/channel.rb
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
app/channel/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
def subscribed
stream_from 'message_channel'
end
def message
p 'ChatChannel ponged in #message'
end
end
REACTJS
import Cable from 'actioncable'; // NPM actioncable
componentDidMount() {
createSocket();
}
createSocket() {
this.cable = Cable.createConsumer('ws://localhost:3000/cable');
this.chats = this.cable.subscriptions.create({
channel: 'ChatChannel', room: 'messaging_room'
}, {
connected: (message) => {
this.cable.connection.webSocket.onmessage = (m) => {
const message = { command: 'message', identifier: JSON.stringify({ channel:
'ChatChannel', room: 'messaging_room' }), data: JSON.stringify({ action: 'message',
data: m.data.message }) };
this.cable.connection.webSocket.send(JSON.stringify(message));
};
},
});
}
来源:https://stackoverflow.com/questions/59476060/how-to-send-a-pong-in-response-to-ping-reactjs-rails-action-cable