追記(解決済み)
リアル・タイムではありませんが、チャットを送ることに成功しました!
>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チャンネルまわりがうまくいってないのかと疑っています
お手数おかけしますがよろしくおねがいします
回答1件
あなたの回答
tips
プレビュー