在 rails 中使用动作电缆,无法从客户端发送到服务器

in rails with action cable, not able to send from client to server

在 rails 中使用动作电缆,我无法从客户端到服务器接收消息,尽管我可以从服务器发送到通道再到客户端。

你可以在这里看到所有文件,最后我用 cat 展示了它们,因为我展示了在制作程序时使用的所有命令

查看 awpchan_channel.rb 我已经订阅了 def,这有效,其中的 puts 命令将写入服务器。但是 def receive(data) 永远不会运行。我在那里写了一个 puts 但它没有执行。

但我在 js 文件中确实有一行用于从客户端向服务器发送字符串。 App.awpchan.send('This is a cool chat app.'); 但它并没有这样做。

我确实在 coffeescript 中有它,但也没有这样做。

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(我将文件名和扩展名重命名为 oldawpchan.oldcoffee,因为我我没有使用它,而是使用 theawpchan.js)

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(空白)

这是我创建程序的方式

~/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

已添加

应用 arieljuod 的建议,在 js 文件中,将发送行放在连接方法的主体中。以免发送太早。

这改善了情况,现在我收到这条消息

就在服务器说

之后
AwpchanChannel is transmitting the subscription confirmation
AwpchanChannel is streaming from abcdstrm

它现在给出这个错误(这将是发送命令执行时)

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...

第一个问题是您在正确初始化通道之前调用了send方法,请先等待它连接。

第二件事是 send 方法需要一个具有参数名称的对象,以便服务器可以以某种方式识别它:

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/

由 barlop 添加了详细说明

在服务器端你可以做

def received
  puts data["message"]
end