2010-06-07 5 views
4

В настоящее время мы работаем над API для существующей системы.Требования к пользовательскому API

Он в основном обертывает некоторые веб-запросы в виде простой в использовании библиотеки, которую сторонние компании должны иметь возможность использовать с нашим продуктом.

В качестве части API существует механизм событий, при котором сервер может перезвонить клиенту через постоянное соединение сокетов.

Чтобы минимизировать нагрузку на сервер, мы хотим иметь только одно подключение на компьютер. В настоящее время для каждого процесса открыт сокет, и это может вызвать проблемы с загрузкой, если у вас есть несколько приложений, использующих API.

Итак, мой вопрос: если мы хотим развернуть наш API как единую автономную сборку, то как лучше всего исправить нашу проблему?

Пару вариантов мы думали:

  • Напишите вне процесса COM объекта (не знаю, если это работает в .NET)
  • Включите второй файл программы, которые потребуются для проведения мероприятий , она должна была бы самой единственной инстанции, и открыть именованный канал или что-то для общения через несколько процессов
  • Extract этот исполняемый файл из внедренного ресурса и не выполнить его

None из тех, которые действительно кажутся идеальными.

Любые лучшие идеи?

+2

Как насчет службы Windows, работающей в фоновом режиме? – dtb

+0

Это похоже на развертывание exe вместе с сборкой, но для этого потребуется больше работы. Мы надеялись, что сторонняя сторона сможет развернуть приложение, используя наш API, просто ссылаясь на сборку. Мы могли бы завершить этот маршрут и создать модуль msi/merge, который третьи стороны должны были бы установить вместе со своим приложением. – jonathanpeppers

+0

@Jonathan: не повторяйте в заголовке теги («C# .Net»). –

ответ

0

Лучшее решение, которое мы придумали, чтобы создать службу Windows, которая открывает именованный канал для управления несколькими клиентскими процессами через один сокет-соединение с сервером.

Тогда наш API сможет определить, запущена/установлена ​​служба и отпадает ли она обратно, чтобы создать собственное подключение для клиента.

Третьи стороны могут решить, хотят ли они связывать услугу с их продуктом или нет, но основные приложения из нашей системы будут установлены.

Я отмечу это как ответ в течение нескольких дней, если у вас нет лучшего варианта. Я надеялся, что есть способ выполнить нашу сборку как новый процесс, но все дороги для этого не кажутся очень надежными.

0

Вы имеете в виду что-то вроде Net.TCP port sharing?

+0

Я должен был упомянуть еще одно требование: наш API должен быть только .Net 2.0 для поддержки более широкой сторонней аудитории. Это означает, что WCF нельзя использовать, мы делаем все с помощью HttpWebRequest или класса Socket для событий. – jonathanpeppers

0

Вы можете исправить порт на стороне клиента при открытии сокета, скажем, 45534. Поскольку один порт может быть открыт только одним процессом, только один процесс за один раз сможет открыть подключение сокета к серверу.

+0

Клиент не слушает, наше приложение не будет работать через брандмауэры. Клиент устанавливает соединение на сервере и ожидает вывода, возвращаемого сервером, так работают наши события. – jonathanpeppers

0

Ну, есть много способов решить эту проблему, как это выражено во всех ответах и ​​комментариях, но, возможно, это более простой способ использования - это просто хранить глобальный статус в месте, доступном для всех пользователей текущего компьютера (может быть, у вас могут быть разные пользователи, зарегистрированные на компьютере), где вы храните ВОЗ, имеет право открыть это. Что-то вроде «блокировки», как используется для вызова. Этот магазин может быть полем в локальной или интрасети, простом файле или что-то еще. Таким образом вам не нужно создавать или распространять дополнительные двоичные файлы.

+0

Я думаю, вы предполагаете, что этот API доступен только для чтения и не изменяется. Наш API обслуживает данные в реальном времени и дает третьим сторонам возможность изменять данные. API также может давать события в режиме реального времени, и это то, где наша проблема. – jonathanpeppers

+0

Я вижу, да, я принял неизменность, которой не существует в вашем API. Ну, если мне нужно выбрать один из уже высказанных вариантов, я думаю, что более понятный вариант - это тот, который имеет отдельный процесс (услугу или нет), управляющий соединением на машину на сервере, а затем добавляет к протоколу связи возможность определить, какой клиентский процесс является событием реального времени. Кроме того, этот дополнительный слой позволит вам легко расширить логику в будущем (скажем, включить второй канал связи). Если вы выберете этот вариант, имейте это в виду, сеть и серверы должны ускориться в будущем. – someone

0

Когда клиент подключается к вашему серверу, вы создаете новый поток для его обработки (а не процесс). Вы можете сохранить его IP-адрес в статическом словаре (разделяемом между всеми потоками). Что-то вроде:

static Dictionary<string, TcpClient> clients = new Dictionary<string, TcpClient>(); 

//This method is executed in a thread 
void ProcessRequest(TcpClient client) 
{ 
    string ip = null; 
    //TODO: get client IP address 

    lock (clients) 
    { 
     ... 
     if (clients.ContainsKey(ip)) 
     { 
     //TODO: Deny connection 
     return; 
     } 
     else 
     { 
     clients.Add(ip, client); 
     } 
    } 
    //TODO: Answer the client 
} 
//TODO: Delete client from list on disconnection 
+0

Наша реализация на сервере не имеет значения (и Linux-сервер не использует ничего подобного C# (Mono) BTW). Проблема, с которой мы хотим справиться, состоит в том, чтобы уменьшить количество подключений, которые клиент открыл для 1 на машину. Мы хотим сделать это, потому что клиентский ПК может иметь 10-15 приложений, используя наш API сразу. – jonathanpeppers

Смежные вопросы