Ваш план наличия агента на удаленной машине - это практически требование для обхода брандмауэров и других подобных проблем, с которыми вы столкнетесь. Здесь не указаны подробности, относящиеся к делу, поэтому я собираюсь сделать некоторые предположения.
Я предполагаю, что вы хотите, чтобы удаленный сервер принимал все сообщения. Другими словами, если удаленный сервер выходит из строя и возвращается, сообщения, отправленные в то время, когда он был отключен, все еще должны быть доступны. Я также собираюсь предположить, что для «разговора» в реальном времени между локальным сервером и удаленным сервером не требуется - чтобы удаленный сервер получал сообщение и действовал, когда это удобно для этого сервера.
С такими допущениями вам лучше использовать систему обмена сообщениями в очереди, такую как RabbitMQ, Amazon SQS или Azure Queue Service. Вы можете создать очередь для каждого удаленного сервера (с предсказуемым именем, чтобы удаленный агент мог его найти), и локальный сервер мог добавлять сообщения в очередь по мере необходимости. Агент на удаленном сервере будет читать из очереди и действовать в соответствии с ней (возможно, это действие просто вызывает другой API и передает любые данные). При наличии очереди вы гарантируете, что удаленный сервер получит все предназначенные для него сообщения, даже если этот сервер не работает во время отправки сообщения. Это также устраняет тесную связь между удаленным сервером и конкретным внутренним сервером, что значительно повышает вашу масштабируемость и масштабируемость удаленного клиента (в случае, если они хотят иметь 2 сервера с работающими агентами)
Кстати, если у вас есть требование к двум серверам обмениваться информацией в режиме реального времени, вы можете отправить сообщение в очередь, чтобы удаленный сервер «позвонил мне», и в этом случае удаленный сервер открывает веб-сокет на внутренний сервер только для связи, которая требует более своевременного взаимодействия. Другое взаимодействие, которое не является чувствительным ко времени, может использовать очередь запросов, как описано выше, и аналогичную очередь ответов для удаленного сервера, чтобы публиковать ответы для внутреннего сервера, чтобы извлечь из очереди. Если в каждом сообщении имеется идентификатор разговора, это также позволило бы обеспечить масштабное внутреннее масштабирование.
Еще одно примечание, в зависимости от вашего варианта использования длительные сообщения могут быть преимуществом. Также обратите внимание на Kafka, AWS Kinesis или Azure Event Hubs.