액션 케이블에 대한 간단한 가이드

14667 단어 railstutorialruby
액션 케이블은 WebSocket을 구현하는 Rails 방식입니다. 일부 Rails 마법이 있습니다.

이 앱의 저장소here

그것을 사용하는 이유



일반적으로 클라이언트는 요청을 통해 서버에 연결합니다.


ActionCable을 사용하면 클라이언트와 서버 간에 열린 연결을 생성하여 통신 흐름을 허용합니다.

예시:



간단한 블로그(게시물 및 댓글)와 해당 게시물을 읽는 여러 사용자가 있습니다. 한 사용자가 댓글을 추가하면 다른 사용자는 절대 알 수 없습니다.


하지만 ActionCable의 열린 연결로 해당 게시물에 대한 즉각적인 업데이트를 받을 수 있습니다 🔥

그것을하는 방법



우선 게시물에 대한 채널을 생성합니다. 이 클래스는 수신하는 모든 클라이언트에 업데이트를 브로드캐스트할 수 있습니다.

rails generate channel posts


그러면 몇 가지 파일이 생성됩니다.

      create    test/channels/posts_channel_test.rb
      create  app/channels/posts_channel.rb
   identical  app/javascript/channels/index.js
   identical  app/javascript/channels/consumer.js
      create  app/javascript/channels/posts_channel.js



메시지 보내기



우리는 새로 생성된 posts_channel.rb로 작업할 것입니다.

스트리밍할 채널을 지정하고 싶기 때문에 id 매개변수를 전달하고 레일에 해당 게시물에 대한 스트림을 만들도록 요청할 수 있습니다.

class PostsChannel < ApplicationCable::Channel
  def subscribed
    post = Post.find(params[:id])
    stream_for post
  end
end


이제 앱의 어느 곳에서나 PostsChannel을 호출하고 해당 게시물을 듣고 있는 모든 사람에게 무언가를 브로드캐스트하도록 요청할 수 있습니다.

PostsChannel.broadcast_to(@post, hello world)


댓글이 생성될 때마다 게시물 채널에 댓글을 브로드캐스트하기 위해 다음을 만들기 작업에 추가합니다.

# app/controllers/comments_controller.rb

def create
  @comment = @post.comments.new(comment_params)
    if @comment.save
      PostsChannel.broadcast_to(@post, @comment.body)
      redirect_to @post, notice: "Comment was successfully created."
    else
      render :new
    end
end


그리고 아무도 이 방송을 듣고 있지 않기 때문에 지금까지는 아무 일도 하지 않습니다. 앞으로 나아가 다!

메시지 수신



신중한 설정:



저는 모든 소비자에 대해 별도의 파일을 생성하는 것을 좋아하지 않으며 보기의 스크립트 태그에서 연결하는 것을 선호합니다. 연결이 필요한 뷰만 생성하는 별도의 프런트 엔드처럼 느껴집니다.
이렇게 하려면 다음 스니펫을 app/javascript/channels/index.js에 추가합니다.

// Expose action cable
import * as ActionCable from '@rails/actioncable'
window.App || (window.App = {});
window.App.cable = ActionCable.createConsumer();


참고: Webpacker가 도입된 Rails 6까지 케이블was the default according to official docs 노출
app/javascript/channels/posts_channel.js에서 파일을 생성하기 전에 사용한 레일 생성기
사용하지 않는 이유는 다음과 같습니다.
  • 항상 필요하므로 무엇을 넣든 앱의 모든 페이지에서 실행됩니다
  • 모든 사람이 업데이트를 받기 위해 연결을 여는 것이 아니라 게시물 쇼 페이지에 있는 사람만

  • 따라서 생성된 posts_channel.js 🗑를 삭제할 수 있습니다.

    그리고 포스트 쇼 페이지에서 방송을 듣기 위한 코드를 추가합니다.

    <!-- app/views/posts/show.html.erb -->
    
    <script>
      App.cable.subscriptions.create({ channel: "PostsChannel", id: "<%= @post.id %>" }, {
        connected() {
          console.log("Connected to the channel:", this);
        },
        disconnected() {
          console.log("Disconnected");
        },
        received(data) {
          console.log("Received some data:", data);
        }
      });
    </script>
    


    이제 블로그 게시물 페이지를 열면 터미널에서 연결된 메시지와 이 연결을 가능하게 하는 일부 Rails 마법을 볼 수 있습니다.

    posts:Z2lkOi8vYWN0aW9uY2FibGUtYXBwL1Bvc3QvMg는 우리가 posts_channel 파일에서 stream_for post에 지시했을 때 rails에 의해 생성된 채널의 이름입니다.

    완료되었습니다! 🎉
    ~거의~

    위의 스크립트는 데이터를 수신했지만 페이지에 표시하지 않습니다. 댓글을 수신하면 목록에 댓글을 추가하도록 업데이트할 수 있습니다.

    App.cable.subscriptions.create({ channel: "PostsChannel", id: "<%= @post.id %>" }, {
      received(comment) {
        el = document.createElement('li');
        el.innerHTML = comment;
        document.querySelector('ul').appendChild(el)
      }
    });
    


    (모든 기능은 옵션으로, 연결이 끊긴 것과 연결된 것은 제거했습니다)

    이제 앱이 Action Cable을 통해 수신하는 모든 브라우저와 통신합니다.


    전체 코드 저장소: GitHub: actioncable-app

    참조



    레일 가이드:
    https://guides.rubyonrails.org/action_cable_overview.html
    헤로쿠 가이드:
    https://blog.heroku.com/real_time_rails_implementing_websockets_in_rails_5_with_action_cable
    Cable.yml 구성:
    https://github.com/rails/rails/issues/28118
    특정 페이지용 케이블:
    https://stackoverflow.com/questions/39597665/rails-actioncable-for-specific-pages
    https://stackoverflow.com/questions/36438323/page-specific-actioncable
    좋은 JS 구독 예:
    https://stackoverflow.com/questions/39597665/rails-actioncable-for-specific-pages
    https://samuelmullen.com/articles/introduction-to-actioncable-in-rails-5/
    https://stackoverflow.com/questions/36266746/actioncable-not-receiving-data
    ActiveJob과 함께 사용
    https://www.pluralsight.com/guides/creating-a-chat-using-rails-action-cable
    ReactNative의 케이블
    https://stackoverflow.com/questions/43510021/action-cable-not-receiving-response-on-client
    애니케이블
    Action Cable vs AnyCable: fight! | Nebulab

    좋은 웹페이지 즐겨찾기