Рубрики
Без рубрики

Создание интегрированной игры для чата Twitch

Находясь в изоляции Короны, я наблюдал за некоторыми подергивающимися потоками и задавался вопросом, будет ли это так… С тегами java, irc, twitch, stomp.

Находясь в изоляции Короны, я наблюдал за некоторыми потоками 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
    
    
        org.springframework.boot
        spring-boot-starter-websocket
    

    @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();
        }
    }

Это настраивает простой брокер сообщений и конечную точку 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

Некоторые полезные ресурсы:

Оригинал: “https://dev.to/tomcools/building-a-twitch-chat-integrated-game-1l0j”