Я пишу игру на основе серверно-клиентской архитектуры на Java.
По причинам дизайна я хотел бы использовать асинхронные вызовы для передачи действий клиента на сервер, а также асинхронные обратные вызовы для передачи результатов указанных действий обратно клиенту. Асинхронные вызовы позволяют буферизовать действия клиента. Буферизация с очередями позволяет выполнять простую однопоточную обработку действий клиента.
На данный момент мой серверный и клиентский код довольно симметричны. Они создают реестр, затем экспортируют и связывают себя.
Асинхронность достигается за счет буферизации входящих действий или результатов в ConcurrentLinkedQueue. Фактическая обработка выполняется потоком, работающим через равные промежутки времени.
Однако эта текущая архитектура не работает, когда клиенты защищены брандмауэром или находятся за NAT. В этом случае сервер просто не сможет связаться с клиентами, чтобы отправить им результаты.
Кроме того, в этой текущей архитектуре сервер не знает, какой клиент отправил данное действие, если только не введен избыточный уровень аутентификации или обработки сеанса. Это допускает поддельные действия и мошенничество.
Я думал о возможных решениях, но не нашел подходящего:
Клиент вытягивает вместо сервера. На сервере может быть метод, который клиенты периодически вызывают для получения своих результатов. Однако такой подход кажется очень уродливым, он вносит дополнительные задержки, проблемы с пропускной способностью и синхронизацией. Не решает проблему подделки действий. Прямые уведомления также очень предпочтительны.
Соединения TCP сами по себе допускают двустороннюю связь и могут определенно идентифицировать клиентов, поэтому RMI или JRemoting может быть взломаны для их поддержки, но я не знаю, как это сделать, и я не знаю ни о каких существующее решение.
Прохождение сообщений. Я не уверен, поддерживают ли структуры передачи сообщений аутентификацию/сеансы или идентификацию клиента. Я бы определенно потерял удаленные методы.
Я считаю, что правильным решением будет найти инфраструктуру удаленного вызова методов, которая поддерживает все вышеперечисленное.
Итак, в двух словах, я ищу способ:
- вызвать сервер асинхронно или передать ему сообщение
- вызвать клиента асинхронно или передать ему сообщение, даже за брандмауэром или NAT
- идентифицировать клиента, отправляющего действие
- желательно иметь возможность вызывать методы, а не просто передавать сообщения
- сохраните возможность легко протестировать его с помощью JUnit и Mockito (несколько клиентов на машину)
Существуют ли какие-либо фреймворки для удаленного вызова методов с их поддержкой? Который лучший?