in rails with action cable, I can't get a message from client to server, though I can send from server to channel to client.
You can see all the files here and at the end i've shown them with cat as I show all commands used in the making of the program
Looking in awpchan_channel.rb I have def subscribed, that works, a puts command in there will write to the server. But def receive(data) never runs. I wrote a puts in there and it isn't executing.
But I do have a line in the js file that is meant to send a string from client to server. App.awpchan.send('This is a cool chat app.');
But it isn't doing it.
I did have it in coffeescript but that didn't do it either.
config/routes.rb
Rails.application.routes.draw do
mount ActionCable.server, at: '/cable'
root 'application#index'
end
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def index
ActionCable.server.broadcast 'abcdstrm', 'zzz'
end
end
app/channels/awpchan_channel.rb
class AwpchanChannel < ApplicationCable::Channel
def subscribed
stream_from "abcdstrm"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
def receive(data)
puts "RECEIVE BY SERVER"
end
end
app/assets/javascripts/channels/awpchan.coffee (which I renamed the filename and extension of to oldawpchan.oldcoffee, as i'm not using it, am using theawpchan.js instead)
App.awpchan = App.cable.subscriptions.create "AwpchanChannel",
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
# Called when there's incoming data on the websocket for this channel
alert(data)
App.awpchan.send 'This is a cool chat app.'
app/assets/javascripts/theawpchan.js
App.awpchan = App.cable.subscriptions.create("AwpchanChannel", {
connected: function() {},
disconnected: function() {},
received: function(data) {
return alert(data);
}
});
App.awpchan.send('This is a cool chat app.');
// http://js2.coffee/
app/views/application/index.html.erb (which is blank)
Here is how I created the program
~/rubymac$ cd channeltests
~/rubymac/channeltests$ mkdir channeltest1
~/rubymac/channeltests$ cd channeltest1
~/rubymac/channeltests/channeltest1$ rails new . >nul
~/rubymac/channeltests/channeltest1$ vi config/routes.rb
~/rubymac/channeltests/channeltest1$ cat config/routes.rb
Rails.application.routes.draw do
mount ActionCable.server, at: '/cable'
root 'application#index'
end
~/rubymac/channeltests/channeltest1$ mkdir app/views/application
~/rubymac/channeltests/channeltest1$ touch app/views/application/index.html.erb
~/rubymac/channeltests/channeltest1$ vi app/controllers/application_controller.rb
~/rubymac/channeltests/channeltest1$ cat app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def index
ActionCable.server.broadcast 'abcdstrm', 'zzz'
end
end
~/rubymac/channeltests/channeltest1$ rails generate channel awpchan
Running via Spring preloader in process 4020
create app/channels/awpchan_channel.rb
identical app/assets/javascripts/cable.js
create app/assets/javascripts/channels/awpchan.coffee
~/rubymac/channeltests/channeltest1$ vi app/channels/awpchan_channel.rb
~/rubymac/channeltests/channeltest1$ cat app/channels/awpchan_channel.rb
class AwpchanChannel < ApplicationCable::Channel
def subscribed
stream_from "abcdstrm"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
def receive(data)
puts "RECEIVE BY SERVER"
end
end
~/rubymac/channeltests/channeltest1$ vi app/assets/javascripts/channels/awpchan.coffee
~/rubymac/channeltests/channeltest1$ cat app/assets/javascripts/channels/awpchan.coffee
App.awpchan = App.cable.subscriptions.create "AwpchanChannel",
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
# Called when there's incoming data on the websocket for this channel
alert(data)
App.awpchan.send 'This is a cool chat app.'
~/rubymac/channeltests/channeltest1$ cd app/assets/javascripts/channels/
~/rubymac/channeltests/channeltest1/app/assets/javascripts/channels$ mv awpchan.coffee oldawpchan.oldcoffee
~/rubymac/channeltests/channeltest1/app/assets/javascripts/channels$ vi oldawpchan.oldcoffee
~/rubymac/channeltests/channeltest1/app/assets/javascripts/channels$ vi theawpchan.js
~/rubymac/channeltests/channeltest1/app/assets/javascripts/channels$ cat theawpchan.js
App.awpchan = App.cable.subscriptions.create("AwpchanChannel", {
connected: function() {},
disconnected: function() {},
received: function(data) {
return alert(data);
}
});
App.awpchan.send('This is a cool chat app.');
// http://js2.coffee/
~/rubymac/channeltests/channeltest1/app/assets/javascripts/channels$ cd ../../../
~/rubymac/channeltests/channeltest1/app$ cd ..
~/rubymac/channeltests/channeltest1$ rails s
=> Booting Puma
=> Rails 5.2.3 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.1 (ruby 2.5.0-p0), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop
Started GET "/" for 127.0.0.1 at 2019-04-21 23:40:55 +0100
Processing by ApplicationController#index as HTML
[ActionCable] Broadcasting to abcdstrm: "zzz"
Rendering application/index.html.erb within layouts/application
Rendered application/index.html.erb within layouts/application (1.5ms)
Completed 200 OK in 469ms (Views: 430.1ms | ActiveRecord: 0.0ms)
Started GET "/cable" for 127.0.0.1 at 2019-04-21 23:41:25 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2019-04-21 23:41:25 +0100
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
AwpchanChannel is transmitting the subscription confirmation
AwpchanChannel is streaming from abcdstrm
added
Applying arieljuod's suggestion, within the js file, putting the send line within the body of the connect method. So that it doesn't send too early.
That improves things, now I get this message
just after the server says
AwpchanChannel is transmitting the subscription confirmation
AwpchanChannel is streaming from abcdstrm
it gives this error now (this would be when the send command executes)
Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"AwpchanChannel\"}", "data"=>"\"This is a cool chat app.\""}) [NoMethodError - undefined method `except' for "This is a cool chat app.":String]: /usr/local/lib/ruby/gems/2.5.0/gems/actionc...
The first problem was that you were calling the send
method before the channel is properly initialized, wait for it to get connected first.
The second thing is that the send
method expects an object with the name of the parameter so the server can identify it somehow:
App.awpchan.send({message: 'This is a cool chat app.'});
App.awpchan = App.cable.subscriptions.create("AwpchanChannel", {
connected: function() {
App.awpchan.send({message: 'This is a cool chat app.'});
},
disconnected: function() {},
received: function(data) {
return alert(data);
}
});
// http://js2.coffee/
added elaboration by barlop
And at the server side you can do
def received
puts data["message"]
end