#ruby-on-rails #redis #actioncable
#ruby-on-rails #redis #actioncable
Вопрос:
Я создаю приложение для обмена сообщениями в Rails 6. Там, где у меня есть контроллер с именем chatroom, когда зарегистрированный пользователь вводит сообщение, он вызывает messages_controller.
messages_controller.rb выглядит следующим образом:
class MessagesController < ApplicationController
before_action :require_user
def create
message = current_user.messages.build(message_params)
if message.save
# redirect_to root_path
ActionCable.server.broadcast 'chatroom_channel',
{ title: message.body, body: message.body }
end
end
private
def message_params
params.require(:message).permit(:body)
end
end
The chatroom_channel.js в javascript / каналы:
import consumer from "./consumer"
consumer.subscriptions.create("ChatroomChannel", {
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
window.alert('hi')
window.console.log('hi')
}
});
Но по какой-то причине я не вижу никаких предупреждений или входа в браузер.
Стандартный вывод с сервера после ввода сообщения:
Started POST "/message" for 127.0.0.1 at 2020-08-27 03:02:08 0530
Processing by MessagesController#create as HTML
Parameters: {"authenticity_token"=>"dhkn32ve1N4eIK4Vgg00KcfP/kuEhfhPHGvTLXKlD2c1rtB/9DQTNudSME7sKL4cxe3nS2lQexXhtdLES9mHjg==", "message"=>{"body"=>"Hello, this is a message!!"}, "commit"=>""}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:5:in `current_user'
(0.1ms) begin transaction
↳ app/controllers/messages_controller.rb:7:in `create'
Message Create (1.2ms) INSERT INTO "messages" ("body", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["body", "Hello, this is a message!!"], ["user_id", 1], ["created_at", "2020-08-26 21:32:08.730711"], ["updated_at", "2020-08-26 21:32:08.730711"]]
↳ app/controllers/messages_controller.rb:7:in `create'
(5.8ms) commit transaction
↳ app/controllers/messages_controller.rb:7:in `create'
[ActionCable] Broadcasting to chatroom_channel: {:title=>"Hello, this is a message!!", :body=>"Hello, this is a message!!"}
No template found for MessagesController#create, rendering head :no_content
Completed 204 No Content in 28ms (ActiveRecord: 7.4ms | Allocations: 4404)
Started GET "/cable" for 127.0.0.1 at 2020-08-27 03:02:15 0530
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2020-08-27 03:02:15 0530
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: keep-alive, Upgrade, HTTP_UPGRADE: websocket)
ChatroomChannel is transmitting the subscription confirmation
config/cable.yml
Файл имеет это содержимое:
development:
adapter: redis
url: redis://localhost:6379/1
test:
adapter: test
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: MessageMe_production
У меня есть redis gem в файле Gemfile, а также сервер redis, работающий на 6379. Сервер rails работает на порту 8080.
routes.rb:
Rails.application.routes.draw do
mount ActionCable.server, at: '/cable'
post 'message', to: 'messages#create'
delete 'logout', to: 'sessions#destroy'
post 'login', to: 'sessions#create'
get 'login', to: 'sessions#new'
get 'chatroom/index'
get 'chatroom', to: 'chatroom#index'
get 'chatroom/help'
root to: 'chatroom#index'
end
Если я вставлю console.log('Hello!')
внутри connected()
функции, я смогу увидеть это в браузере.
Да, данные сохраняются, и если я добавлю некоторый код if message.save
, который будет выполнен. Тем не менее, функция receive() ActionCable не работает.
Я что-то упускаю?
Комментарии:
1. Имя канала на стороне ruby указано как ‘chatroom_channel’, но канал на стороне JS — ‘ChatroomChannel’. Они должны быть одинаковыми.
2. Здравствуйте, файл Ruby называется chatroom_channel.rb, а файл JS называется chatroom_channel.js . Он был создан командой
rails g channel chatroom
. Я только что изменил полученную функцию в файле JS и cable. файл yml для вставки redis, потому что async также не работал. Изменение имен также не сработало. Если я ошибаюсь, можете ли вы точно указать, что нужно изменить?3. Это была нелепая ошибка. Я забыл добавить
stream_from 'chatroom_channel'
в файл chatroom_channel.rb. Он работает отлично 🙂