Это пост, который, таким образом, контрабангирование на предыдущей публикации я выполнял на прошлой неделе. Я бы сделал проект Capstone в Flatiron на несколько недель, который использовал P5.js и Websockets для создания совместного холста для пользователей для создания аудио визуализатора вместе. Если вы заинтересованы, вот ссылка.
В любом случае, на протяжении всего проекта я обнаружил, что простое решение заимствования чужих сложных компонентов или классов реагирования не соответствовала относительно определенному способу, в котором работал мой проект. В частности, мне нужно было много контроля над поведением эскиза P5, а также WebSocket, поскольку они были хлебом и маслом моего проекта. Мне нужна открытое соединение со всеми пользователями на одном хоменте, и когда один пользователь редактирует форму P5, что редактирование будет представлять всех различных пользователей или «подписчиков» в ApaceCable Jargon. Конечно, вы могли бы использовать пользователи постоянно запрашивать обновления с сервера через HTTP-запросы, в противном случае известен как опрос, но Websockets позволяют соединению между клиентом и сервером оставаться открытым таким образом, чтобы информация может свободно течь взад-вперед. Опыление означало бы, что мой сервер будет отправиться на перегрузку с запросами пинги.
Кроме того, прежде чем я попаду в это. Это не будет чрезвычайно тщательным объяснением того, как Websockets работают в рельсах, больше моей реализации. Дженнифер Инграм сделал фантастическую работу, объясняя их в ее посте здесь И я определенно рекомендую вам проверить это. Мой проект немного больше конкретного использования случая использования, так думал, что это будет ценным, чтобы поделиться независимо от.
Теперь к коду!
Рельсы сделали его супер удобным, чтобы сделать действительно интересные вещи с помощью AccuredCable, что позволяет легко потокотать, подключенные к конкретным моделям. В моем случае у меня была фотография модель (я пытался сделать его под названием «Холст», но рельсы последовательно запутались, думая, что единственная форма холста была «Canva». Супер раздражающий) у которого был собственный канал для потока. Чтобы генерировать это все, что вам нужно:
rails g channel [channel_name]
Это создаст файл для вас, который действует как контроллер для HTTP. Мой выглядел как:
class PicturesChannel < ApplicationCable::Channel def subscribed # stream_from "some_channel" end def unsubscribed # Any cleanup needed when channel is unsubscribed end end
В других примерах пользователи будут генерировать несколько каналов (например, One для чата и один для сообщений, которые будут поток в чатную модель), и это может быть хорошим способом сегмента и контроля потока данных. Для меня я хотел, чтобы код был таким же простым, насколько это возможно, чтобы не получить тоже в сорняках, поэтому я застрял только одним каналом.
На самом деле есть только один важный компонент, и это добавляет одну строку на ваши маршруты.
Rails.application.routes.draw do ... mount ActionCable.server => '/cable' end
Это просто устанавливает, где вы скажете свой интерфейс, чтобы установить кабель. По сути, вы хотите пойти на этот момент, заполнив необходимую информацию в вашем методе подписки. В качестве комментариев под методом подписки указывают, вы укажете строку, для которой подписчики или клиенты на переднем конце будет ссылкаться на. Подумайте об этом, как имя телевизионной станции, и мы должны убедиться, что наши пользователи имеют правильный канал одновременно. Например.
class PicturesChannel < ApplicationCable::Channel def subscribed # stream_from "some_channel" stream_from "pictures_channel_#{params[:id]}" end def unsubscribed # Any cleanup needed when channel is unsubscribed end end
Я кормил шаблон литерал, чтобы каждый канал соответствовал конкретным изображениям (или пособиям) на основе их идентификатора. Это становится ясно, когда мы получаем отреагируем, но мы можем получить доступ к значениям, подаваемым на бэкэнду, используя парам, как наши контроллеры.
Сейчас реагировать
Чтобы убедиться, что вся картина появляется, я прыгаю, чтобы реагировать так, что мы не будем попадать в бэкэнде. Первое, что вам нужно, это зависит, и вы можете импортировать это двумя способами. Как узел:
npm install actioncable --save
Или как требование в самого компонента вам нужно установить:
const actioncable = require("actioncable")
Я пошел с требованием, потому что я следовал примерному примеру, который я видел в Интернете, но Дженнифер Инграм делает это как узел, поэтому обращайтесь к ней, если вы хотите этого таким образом.
Далее нам нужно установить кабель, и мы просто будем кормить на нашем маршруте, основанном на бэкэнде:
class Canvas extends React.Component { ... componentDidMount() { ... this.cable = actioncable.createConsumer('ws://localhost:3000/cable'); }
Я бы узнал, что получение данных лучше всего подходит для монтажа компонентов, поэтому монтаж кабеля, казалось, имел смысл в этом методе жизненного цикла. Это просто устанавливает наш кабель в правильном направлении. Это почти как мы включаем телевизор и просто нужно надевать на правый канал. Это сделано с этим:
this.canvasChannel = this.cable.subscriptions.create({ channel: `PicturesChannel`, id: this.props.paramsId },{ connected: () => { console.log("connected!") }, disconnected: () => {}, received: data => {} })
Этот бит кода устанавливает, где мы подписываемся через кормление в хеш, который указывает строку для ключа канала. Я подал в ключ ID, чтобы я мог знать крюк пользователя до правого холста, используя некоторые реквизиты, которые я его подал. Примечание, строка, которую мы подаем в канал, важнейчательно важны и должны соответствовать имени канала, который мы создали, а не строка, которую мы подавали в функцию stream_from выше. Вы можете создать этот объект канала в любом месте, который вы бы хотели, у меня есть мой на самом деле внутри моего эскиза для P5, потому что полученные данные должны были изменить эскиз P5, когда он работал. Таким образом, полученный обратный вызов должен был иметь соответствующий объем доступа к этим переменным. Более общей случай будет выглядеть так:
this.canvasChannel = this.cable.subscriptions.create({ channel: [name_of_channel] },{ connected: () => {}, disconnected: () => {}, received: data => {} })
Во втором аргументе подключенных, отключенных и полученных ключей являются просто функциями обратного вызова, которые вы можете указать. Такие, как будто вы хотели, чтобы вещи вызвали, как зеленый свет, чтобы включить или выключить, если подключен или отключен, вы будете использовать подключенные и отключенные обратные вызовы, чтобы переключить его. Полученный обратный вызов – это супер важный, хотя и будет запускаться каждый раз, когда данные о том, как данные проходят вниз по каналу с бэкэнда к фронту.
Удивительно, что это все, что нужно на передней части, чтобы ваш кабель и работает. В моем случае метод «Cable.SubScriptions.create» подключит к бэкэнду цистерна, запустите метод подписки и используйте клавишу ID, чтобы создать имя канала, которое будет использовать бэкэнду, чтобы транслироваться, и Freeend будет подписан к. Шаги до сих пор были:
Рельсы
-Хнативный канал – сошельтите маршрут Websocket -give Stream_Rom a a a a rails, чтобы узнать, какой канал транслировать
Реагировать
-Устанавливать Кабель – возглавляет подписку на правильный канал
Это так же, как я могу сделать так, чтобы смысл встречался. Я теперь возьму у вас на примере, где я хотел, чтобы пользователь нажимал на некоторую часть холста, и которые щелкнули, будут отправлять позицию кликов через канал, транслируйте, что всем подписчикам этого канала, а затем у каждого клиента получают и получить каждый клиент Нарисуйте все клиенты пособия.
Поэтому, когда пользователь нажимает на часть холста, то это может вызвать обратный вызов, который отправляет свое положение на задний конец. Мы можем сделать это с одним из методов на нашем объекте канала:
p.mouseClicked = () => { this.canvasChannel.send({ canvas_id: this.props.paramsId, burst: { user_id: [user_id], tune : { x: p.winMouseX, y: p.winMouseY } } }) }
MouseClicked – это хорошая функция P5, которая отвечает каждый раз, когда пользователь нажимает на нашем холсте, а также имеет хорошие переменные, которые держат, где мышь была в это время, «WinMousex» и «WinMousey». Обратитесь к моему сообщению P5 Blog для объяснения фанки «р». Нотация, но это просто объект P5. CanvasChannel.Send Отправьте эти данные на бэкэнд через нашу Weblocket. Теперь для канала, чтобы получить это, мы должны добавить метод в ZOOCKCHANNEL:
class PicturesChannel < ApplicationCable::Channel ... def receive(data) ActionCable.server.broadcast("pictures_channel_#{data['canvas_id']}", data) end end
Этот метод получения принимает аргумент «Данные» и будет запускаться всякий раз, когда данные отправляются через канал на бэкэнду. Линия внизу просто транслирует, что данные на правильный канал. В этом случае мы передаем его данные, которые щелкнули, где щелкнулись, и какой холст они нажали. Rails использует информацию для вещания в правильное имя канала, которое является точной строкой, которую мы использовали в нашей подписной методе «zts_channel _ # {data [‘canvas_id’]}”.
Затем второй аргумент – это фактические данные, через которые мы прошли. Весь этот метод делает ловить то, что мы отправляем, и направляя его на правильное место. Примечание, данные, которые мы кормите в этот метод широковещания, должны быть JSON. Если вы хотите широковещать данные в другом месте, вроде в одном из контроллеров, вы должны убедиться, что это хэш. Он автоматически не сериализует его для вас, если вы кормите в экземпляре модели.
Как только это сделано, данные транслируются обратно по каналу всем подписчикам и достигают нашего объекта подписки на канал Frontend, где проводится полученный метод. Тогда все, что нужно, – это взять позицию щелчка, которую мы отправили, и запустите метод, который отображает его на всех клиентах:
this.canvasChannel = this.cable.subscriptions.create({ channel: `PicturesChannel`, id: this.props.paramsId },{ connected: () => {}, disconnected: () => {}, received: data => { this.handleRecievedClick(data) } })
В P5 это может означать, что в этом месте появляется форма, или в разрыв в этом месте (используя Mo.js ). Как только все настроено, у вас действительно есть свобода отправки на все, что вы хотите. У вас могут быть данные, отправленные с помощью этого изменения, отображают изменения состояния, такие как цвет компонентов, что отображается и т. Д. Есть тонна вещей, которые вы можете сделать с WebSockets за пределами всего чата.
Я надеюсь, что это помогло и не было слишком долго. Не стесняйтесь обращаться, если у вас есть какие-либо вопросы.
Оригинал: “https://dev.to/christiankastner/react-and-actioncable-1gbh”