Находясь в изоляции Короны, я наблюдал за некоторыми потоками Twitch и задавался вопросом, не хотел бы я тоже этим заняться. Я люблю преподавать, и так как мы все в значительной степени застряли в своих домах, может быть, мне стоит попробовать. Это было бы похоже на выступление на конференции, только более ограниченное во взаимодействии… но это то, что мне больше всего нравится в обучении… взаимодействие.
Так что, может быть, Твитч просто не для меня… если не… Что, если бы я мог сделать что-нибудь, чтобы сделать Twitch более интерактивным местом? Что, если бы я мог каким-то образом создать что-то, что стримеры могли бы использовать для развлечения своих зрителей более интерактивным способом?
Пора соорудить что-нибудь дерганое!
Требования
Чтобы оставаться сосредоточенным, вот рекомендации, которые я установил для себя:
- Планка входа должна быть низкой;
- Владелец потока должен иметь контроль;
- Что бы я ни делал, это не должно отвлекать внимание от потока, это должен быть поток;
Эти требования подтолкнули меня к следующему предварительному проекту:
IMG
Чтобы снизить планку входа, я собираюсь создать какую-нибудь веб-игру. Создание его в Javascript/HTML делает его более доступным, так как всем пользователям понадобится браузер. У меня был некоторый предыдущий опыт работы с p5.js , поэтому я собираюсь использовать это снова для этого проекта.
Все, что мне тогда нужно было сделать, это найти способ интегрироваться с Twitch… каким-то образом.
Читайте чат!
Изучая некоторые потоки Twitch, я быстро заметил, что большинство пользователей взаимодействуют со стримером через чат . Если это обычный способ ведения дел, я не собираюсь с этим бороться. Я собираюсь принять это.
Так что теперь мне просто нужно интегрироваться с чатом Twitch и использовать его в качестве входных данных для всего, что я делаю. Я немного беспокоился, что это может оказаться трудной задачей. Я действительно не хотел использовать какие-то инструменты для очистки экрана или что-то еще, чтобы получать сообщения в чате. Эти чувства быстро исчезли, когда я узнал хорошие новости:
Twitch использует IRC!
Для тех из вас, кто, возможно, этого не знает… IRC, или Чат ретрансляции Интернета, – это протокол прикладного уровня, построенный на TCP. Это довольно простой текстовый протокол, который существует уже 30 лет и используется до сих пор.
Мило! Поскольку IRC так распространен, мне нужно было только найти способ подключить свой интерфейс к IRC-чату, и мы готовы к работе. И вот тут-то мой первоначальный план и развалился.
Видите ли, IRC использует TCP. Javascript, по крайней мере, тот вид Javascript, который работает в браузере, не может устанавливать регулярные соединения с TCP-сокетами. Это может показаться удивительным с учетом популярности веб-сайтов. Однако веб-сайты всегда начинаются как HTTP-запрос и “обновляются” до TCP. WebSockets – это отдельный протокол прикладного уровня, точно так же, как IRC – это протокол прикладного уровня. К сожалению, они волшебным образом плохо играют вместе.
Итак… возвращаемся к чертежной доске!
Клиент IRC Java
Похоже, у меня не было другого выбора, кроме как установить пользовательский сервер между моим интерфейсом и чатом Twitch. Я выбрал для приложения Spring Boot, всегда полезно держать рядом некоторые знакомые технологии, когда вы создаете что-то незнакомое.
IMG
Для подключения к IRC Twitch я решил использовать библиотеку PircBotX . Я не собираюсь дублировать их документацию… но я покажу вам, какие настройки я использовал для подключения к Twitch.
Во-первых, вам понадобится учетная запись Twitch и получите токен доступа для вашего приложения. Этот веб-сайт предоставит вам его, если вы войдете в систему.
Затем вам нужно настроить PircBotX , чтобы использовать правильную конфигурацию.
String authToken = "oauth:YOUR_TOKEN"; // Your oauth password from http://twitchapps.com/tmi
String channel = "#tomcools"; // The IRC channel name = Twitch Channel name
Listener listener = // Extend the ListenerAdapter Class
Configuration configuration = new Configuration.Builder()
.setAutoNickChange(false) //Twitch doesn't support multiple users
.setOnJoinWhoEnabled(false) //Twitch doesn't support WHO command
.setCapEnabled(true)
.addCapHandler(new EnableCapHandler("twitch.tv/tags"))
// Twitch by default doesn't send JOIN, PART, and NAMES unless you request it,
// see https://dev.twitch.tv/docs/irc/guide/#twitch-irc-capabilities
.addCapHandler(new EnableCapHandler("twitch.tv/membership"))
.addServer("irc.twitch.tv")
.setServerPassword(authToken)
.addAutoJoinChannel(channel) //Some twitch channel ex. #tomcools
.addListener(listener).buildConfiguration();
bot = new PircBotX(configuration);
bot.startBot();
Далее нам нужно добавить прослушиватель, который будет вызываться всякий раз, когда на IRC-канал поступает новое сообщение. Существует удобный абстрактный класс, который вы можете наследовать . Вам нужно только переопределить методы, которые вы действительно хотите использовать. В нашем случае нам интересно получать сообщения и некоторые отзывы о событиях подключения/отключения.
public class TwitchIrcChatListener extends ListenerAdapter {
private final ChatMessageListener listener;
public TwitchIrcChatListener(final ChatMessageListener listener) {
this.listener = listener;
}
@Override
public void onGenericMessage(GenericMessageEvent event) {
listener.onChatMessageReceived(new ChatMessage(event.getUser().getNick(),event.getMessage()));
}
@Override
public void onConnect(ConnectEvent event) throws Exception {
super.onConnect(event);
listener.onConnect();
}
@Override
public void onDisconnect(DisconnectEvent event) throws Exception {
super.onDisconnect(event);
listener.onDisconnect();
}
}
Как вы можете видеть, я предоставил ChatMessageListener в конструкторе, и все, что я делаю, это передаю сообщение этому слушателю. Определение этого интерфейса довольно простое.
public interface ChatMessageListener {
void onChatMessageReceived(ChatMessage chatMessage);
void onConnect();
void onDisconnect();
}
Хотя это может показаться ненужным уровнем косвенности, это позволяет нам отделить остальную часть приложения от PircBotX рамки. Таким образом, мы можем изменить его с помощью любой другой платформы без необходимости слишком большого рефакторинга.
ТОПАЙТЕ за победой
Теперь, когда мы получаем сообщения чата в бэкэнде Boot, нам все еще нужен был способ передать их на мой интерфейс Javascript. Игра, которую мы создаем, должна быть доступна нескольким разным пользователям, у каждого из которых своя сессия, своя часть системы. Я почти инстинктивно потянулся к веб-сайтам, чтобы выполнить эту задачу… но что-то меня остановило.
Выполняя эти проекты, я всегда стараюсь ограничить количество новых вещей, которые я изучаю. Попытка замять слишком много новых блесток в проекте всегда замедляет меня до темпа, который мне больше не нравится. Мне нужно ощущение прогресса. Имея за спиной интеграцию IRC, я действительно чувствовал, что пришло время для чего-то нового, особенно с тех пор, как У меня было такое чувство, что веб-сайты не очень подходят.
Именно тогда я обнаружил Простой Текстовый протокол обмена сообщениями, или, для краткости, STOMP .
STOMP предоставляет совместимый проводной формат, чтобы клиенты STOMP могли взаимодействовать с любым брокером сообщений STOMP для обеспечения простой и широкой совместимости обмена сообщениями между многими языками, платформами и брокерами. От: https://stomp.github.io/
STOMP напоминает IRC одним очень удобным способом для нашего приложения . Для этого они используют разную терминологию, но оба позволяют отправлять сообщения в указанное местоположение.
- В IRC сообщения могут быть отправлены на КАНАЛЫ пользователи могут *ПРИСОЕДИНИТЬСЯ *.
- В STOMP сообщения могут быть отправлены АДРЕСАТАМ пользователи могут ПОДПИСАТЬСЯ вкл .
Хотя между ними есть некоторая разница, именно это сходство привлекло мое внимание. Помните, что изначально я хотел сделать, это подключить мою интерфейсную игру напрямую к IRC. Что можно сделать вместо этого, так это подключить интерфейс через STOMP к серверной части Spring Boot и использовать эту серверную часть в качестве моста к IRC.
IMG
К счастью для нас, Spring встроила поддержку для запуска брокера STOMP.
org.springframework.boot spring-boot-starter-web @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/stomp-websocket") .setAllowedOrigins("*").withSockJS(); } } org.springframework.boot spring-boot-starter-websocket
Это настраивает простой брокер сообщений и конечную точку STOMP с поддержкой SockJS .
SockJS – это библиотека, которая предоставляет функции, подобные веб-сайтам, она даже использует веб-сайты по умолчанию. Однако он вернется к другим протоколам и стратегиям, если веб-сайты по какой-либо причине недоступны.
Поскольку серверная часть будет функционировать как мост между STOMP и IRC, вполне естественно, что мы хотим запустить/остановить IRC-соединение одновременно с запуском/остановкой соединения с STOMP. Для достижения этой цели мы можем прослушивать Весенние события, которые будут запускаться при запуске/остановке сеанса.
@Autowired (through constructor in project code)
private final SimpMessagingTemplate template;
@EventListener
public void handleSessionConnected(SessionConnectEvent event) {
// Get channel out of event
String channel = SessionEventHelper.extractChannel(event);
// Start a new Chatbridge (see code for details)
chatBridge.start(channel, chatMessage -> {
// Whenever a message arrives, send it to /topic/CHANNEL_NAME through STOMP
template.convertAndSend("/topic/" + channel, chatMessage);
});
}
@EventListener
public void handleSessionDisconnect(SessionDisconnectEvent event) {
// Stop Chatbridge
}
Всякий раз, когда IRC-сообщение принимается по определенному каналу (#название канала) , наш мост разместит сообщение в пункте назначения STOMP с тем же именем (/тема/название канала) . Сохранение сопоставления имен между IRC и STOMP от 1 до 1 немного упрощает управление.
Подключение переднего конца
Теперь все улажено… давайте быстро взглянем на интерфейс.
Интерфейс подключается к Spring с помощью конечной точки, которую мы настроили ранее. Мы используем библиотеку SockJS и оборачиваем ее клиентом Stomp.
const socket = new SockJS('/stomp-websocket');
let stompClient = Stomp.over(socket);
let twitchHandle = // Read from field;
stompClient.connect({channel: twitchHandle}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/'+twitchHandle, function (msg) {
let message = JSON.parse(msg.body);
textReceived(message); // Function our game uses to handle received messages
});
});
Облава
Остальная часть интерфейса, честно говоря, не имеет большого значения. Это просто простая интерфейсная игра на Javascript, написанная с p5.js . Что действительно важно, так это то, что у нас есть какой-то способ получить сообщения чата Twitch вплоть до Javascript.
Проект доступен на моем сайте . Проверьте это, если вы стример. Хотя это всего лишь простая игра, было забавно видеть, как люди участвуют в моем собственном потоке.
Если вы создадите какую-нибудь классную интегрированную игру или приложение для чата Twitch после прочтения этого поста, Я бы с удовольствием попробовал!
Полный код доступен на Github . <3
Некоторые полезные ресурсы:
- Руководство по подключению IRC Twitch
- Руководство по топоту весеннего сообщения
- Документация STOMP
- Документация PircBotX
Оригинал: “https://dev.to/tomcools/building-a-twitch-chat-integrated-game-1l0j”