質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1765閲覧

Deviseを使わずにルームのあるリアルタイムチャットを作りたい

p-plus

総合スコア43

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2019/09/03 19:29

編集2019/09/04 15:47

追記(解決済み)

リアル・タイムではありませんが、チャットを送ることに成功しました!

>verified_user = User.find_by(id: cookies.signed["user.id"])
こちらのコードを書いていたのに、ログインするときにクッキーにユーザー情報を保存させていなかったのが原因でした。
なので下記のように修正しました。

sessions_controller.rbのログインしたときに「cookies.encrypted[:user_id] = @user.id」を追記しました。

ありがとうございました。

前提・実現したいこと

閲覧ありがとうございます。
Deviseを使わずにここにあるリアルタイムチャットを作りたいです。
ここ

発生している問題

一対一のチャットを作るところまでは出来たのですが、そこからルーム別のチャットを作るところで引っかかりました。
ルーム一覧ページ問題なく動いていて、ルームごとのページはmysqlから直接以下のように打ち込んだメッセージが
反映されているのですが、メッセージ入力欄から挿入したメッセージが反映されません。
DB上でも登録されていませんでした。

insert into messages (content,user_id,room_id) values("komento22デスデスsu",1,10);

エンターボタンを押しても送信ボタンを押してもこのようなメッセージが流れるくらいでした

User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1 ↳ app/channels/application_cable/connection.rb:12 An unauthorized connection attempt was rejected Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket) Finished "/cable/" [WebSocket] for 210.153.208.158 at 2019-09-03 19:01:45 +0000 Finished "/cable/" [WebSocket] for 210.153.208.158 at 2019-09-03 19:01:45 +0000 Started GET "/cable" for 210.153.208.158 at 2019-09-03 19:01:55 +0000

一番怪しそうなところ

/app/jobs/message_broadcast_job.rb class MessageBroadcastJob < ApplicationJob queue_as :default def perform(message) ActionCable.server.broadcast "room_channel_#{message.room_id}", message: render_message(message) end private end
connection.rb module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect self.current_user = find_verified_user end private def find_verified_user verified_user = User.find_by(id: cookies.signed["user.id"]) if verified_user && cookies.signed['user.expires_at'] > Time.now verified_user else reject_unauthorized_connection end end end end
room_channel.rb class RoomChannel < ApplicationCable::Channel def subscribed stream_from "room_channel_#{params['room_id']}" end def unsubscribed # Any cleanup needed when channel is unsubscribed end def speak(data) Message.create!(content: data['message'], user_id: current_user.id, room_id: params['room_id']) end end
room.coffee document.addEventListener 'turbolinks:load', -> App.room = App.cable.subscriptions.create { channel: "RoomChannel", room_id: $('#messages').data('room_id') }, 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) -> # メッセージをブロードキャストで受け取った時 # id=messagesにdata['message']を表示させる show_user = $('#show_user').data('show_user') console.log data['chat_user'] console.log show_user if data['chat_user'] == show_user $('#messages').append data['message_right'] else $('#messages').append data['message_left'] speak: (message)-> # メッセージが送信された時 # コンシューマになったRoomChannelのspeakアクションが呼ばれる @perform 'speak', message: message # Viewの'[data-behavior~=room_speaker]'内のtextを引数に実行される # eventはここでは'[data-behavior~=room_speaker]'にあたる $(document).on 'keydown', '[data-behavior~=room_speaker]', (event) -> # Ctrl + returnキーを押すとここで上のApp.roomの:speakが呼ばれる if event.ctrlKey && event.keyCode is 13 # 引数eventのvalueをspeakアクションに渡す App.room.speak event.target.value # eventのvalueを初期化 event.target.value = '' # 中身をsubmitしない event.preventDefault() $(document).on 'click', '.chat_submit', -> App.room.speak $('[data-behavior~=room_speaker]').val() $('[data-behavior~=room_speaker]').val('') event.preventDefault()

###大丈夫かなと思っているところ

/app/models/message.rb class Message < ApplicationRecord validates :content, presence: true belongs_to :user, optional: true belongs_to :room, optional: true # createの後にコミットする { MessageBroadcastJobのperformを遅延実行 引数はself } after_create_commit { MessageBroadcastJob.perform_later self } end
/app/views/rooms/show.html.erbの入力部分抜粋 <div class="input"> <%= text_field nil, nil, 'data-behavior': 'room_speaker', class: 'center-block', style: 'margin-bottom: 20px; width: 100%; max-width: 500px;' %> <br /> <%= button_tag '送信', class: 'chat_submit' %> </div>

キャプチャなど

ルーム一覧画面

ルーム一覧画面

ルーム画面

補足情報

うんともすんとも言わないので、roomチャンネルまわりがうまくいってないのかと疑っています
お手数おかけしますがよろしくおねがいします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

p-plus

2019/09/04 11:29

失礼しました、修正しました
guest

回答1

0

ベストアンサー

User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1 ↳ app/channels/application_cable/connection.rb:12 An unauthorized connection attempt was rejected

とあるので認証できていなさそうです。
usercurrent_user として呼ばれているかチェックする必要がありそうです
p メソッドや pry gem など利用してデバッグしてみてください。

ruby

1 module ApplicationCable 2 class Connection < ActionCable::Connection::Base 3 identified_by :current_user 4 5 def connect 6 self.current_user = find_verified_user 7 end 8 9 private 10 11 def find_verified_user 12 p cookies.signed["user.id"] # cookies.signed["user.id"] にはいっているか チェック 13 verified_user = User.find_by(id: cookies.signed["user.id"]) 14 p verified_user # user はきちんと見つかっているかチェック 15 p cookies.signed['user.expires_at'], Time.now # 条件式とおるかチェック 16 if verified_user && cookies.signed['user.expires_at'] > Time.now 17 verified_user 18 else 19 reject_unauthorized_connection 20 end 21 end 22 23 end 24 end 25

投稿2019/09/04 00:30

unhappychoice

総合スコア1531

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

p-plus

2019/09/04 10:17

ありがとうございます! https://qiita.com/silmisilon/items/8e08435204d8d08d09ff こちらを参考にgemを導入しいただいたコードに変えてみたのですが、コンソールログは特に変わった様子はありませんでした。。 他に開示したほうが良いファイルなどはありますでしょうか?
unhappychoice

2019/09/04 15:49

p しても何も出ないということですかね? であればそもそも find_verified_user が呼ばれていないようなので、 identified_by :find_verified_user してみる等はいかがでしょう
p-plus

2019/09/06 20:50

入れ違いになってしまって申し訳ありません。 追記したとおりおかげさまで原因が特定でき、無事解決しました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問