React를 사용한 Rails 6 ActionCable 기본 사항

ActionCable을 React와 함께 사용하기 위해 알아야 할 사항.



이것은 React를 사용하여 Rails 6에서 기본 ActionCable 기능을 얻는 단계를 안내합니다. 채팅방이 아닌 가장 기본적인 시나리오인 2인 매칭을 사용하겠습니다. 페이지 하단에 저장소에 대한 링크가 있습니다.

먼저 데모 프로젝트를 만들어 봅시다.
rails new ActionCable-demo -T webpack=react
그런 다음 이름이 있는 사용자 모델이 필요합니다.
rails g scaffold User name
다음으로 게임 모델만 필요합니다. 이를 위해 뷰나 컨트롤러를 사용하지 않습니다.
rails g model Game red_user_id:integer blue_user_id:integer
마지막으로 필요한 부분은 ActionCable용 채널입니다. 채널을 생성하기만 하면 대부분의 작업이 자동으로 수행되므로 채널을 생성하기만 하면 됩니다.
rails g channel MatchMaking
이제 Game 및 User 모델에 대한 관계를 설정해야 합니다.

class User < ApplicationRecord
  has_many :blue_games, class_name: 'Game', foreign_key: 'blue_user'
  has_many :red_games, class_name: 'Game', foreign_key: 'red_user'

  def games
    [blue_games, red_games]
  end
end



class Game < ApplicationRecord
  belongs_to :red_user, class_name: 'User'
  belongs_to :blue_user, class_name: 'User'

  def users
    [red_user, blue_user]
  end
end


이제 두 명의 사용자를 사용하여 게임을 만들 때 red_user_id 및 blue_user_id 속성을 자동으로 가져옵니다. 헬퍼 메서드는 일반적인 wants_to 및 has_many 관계를 에뮬레이트합니다.

매치메이킹 채널 설정 시간

class MatchMakingChannel < ApplicationCable::Channel
  @@matches = []

  def subscribed
    stream_from 'MatchMakingChannel'
  end

  def joined(username)
    @@matches.length == 2 ? @@matches.clear : nil
    user = User.find_by(name: username['user'])
    # add the user to the array unless they already joined
    puts '*' * 30
    puts @@matches
    @@matches << user unless @@matches.include?(user)
    if @@matches.length == 2
      game = Game.create!(red_user: @@matches.first, blue_user: @@matches.last)
      ActionCable.server.broadcast 'MatchMakingChannel', game: game
    else
      ActionCable.server.broadcast 'MatchMakingChannel', message: 'waiting for game'
      ActionCable.server.broadcast 'MatchMakingChannel', 'waiting for game'
    end
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
end


이것은 연결하는 데 필요한 모든 것입니다. 이제 프런트 엔드로 이동하여 확인하십시오.

첫 번째 단계는 목적에 맞게 사용자 표시 양식을 조정하는 것입니다. /app/views/users/show.html.erb에서 . 에 id 태그를 추가합니다.
나중에 사용하기 위해 차단합니다.

<p id="notice"><%= notice %></p>

<p id='name'>
  <%= @user.name %>
</p>

<%= link_to 'Edit', edit_user_path(@user) %>
<%= link_to 'Back', users_path %>


이제 React 요소를 추가해야 합니다. ~ 안에
/app/views/layouts.application.html.erb
추가하다
<%= javascript_pack_tag 'index' %>
헤더에 추가하고 index.js/app/javascript/packs/ 생성

import React from 'react';
import ReactDOM from 'react-dom';
import actioncable from 'actioncable';
import App from '../App'

const CableApp = {}
CableApp.cable = actioncable.createConsumer('ws://localhost:3000/cable')

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <App cable={CableApp.cable}/>,
  document.body.appendChild(document.createElement('div')),
)
})


이제 앱 구성 요소가 한 디렉토리 위로 올라갑니다.

import React, { Component } from 'react'

export default class App extends Component {

  constructor(props) {
    super(props)
    this.state = {
      message: 'not joined',
      name: ''
    }
    this.matchMakingChannel = {}
  }



  componentDidMount = () => {
    this.setState({name: document.getElementById('name').textContent.trim()})
    this.matchMakingChannel = this.props.cable.subscriptions.create('MatchMakingChannel', {
      connected: () => {
        this.setState({message: 'joined MatchMaking'})
      },
      received: (data) => {
        if (data.message){
          this.setState({message: data.message})
        }
        if (data.game){
          this.setState({message: 'Game # ' + data.game.id + ' Red user id ' + data.game.red_user_id + ' Blue user id ' + data.game.blue_user_id + '.'})
        }
      },
      joined: (name) => {
        this.matchMakingChannel.perform('joined', {user: name})
      }
    })

  }
  handleJoined = (name) => {
    this.matchMakingChannel.joined(name)
  }
  render() {
    return (
      <div>
        <div>{this.state.message}</div>
        <button type="button" onClick={() => this.handleJoined(this.state.name)} >Join Game</button>
      </div>
    )
  }
}


Rails 서버를 시작하고 http://localhost:3000/users로 이동하여 새 사용자를 생성합니다. 두 번째 창에서 이 작업을 반복하고 두 번째 사용자가 게임 참가를 클릭하면 두 사용자의 상태 업데이트를 확인합니다. 이것이 실제 게임이라면 플레이어를 위한 개인 공간 역할을 하는 액션 케이블이 스트리밍되는 게임 개체가 있을 것입니다. 둘 다 게임 채널에 연결되면 MatchMaking에서 연결을 끊을 수 있습니다.

Clone this repo here.

좋은 웹페이지 즐겨찾기