Имеется постоянно пополняемая БД. Сервер должен выбирать данные из БД и отдавать клиентам, как синхронно (сразу после запроса клиента), так и асинхронно. Другими словами, между клиентами и сервером устанавливается двустороннее соединение. Целевая платформа для сервера — Debian, для клиентов — Windows, Android (+ веб-интерфейс, но тут уже без асинхронности). Все взаимодействия через интернет (у сервера белый IP; клиент может быть где хочешь — за NAT, за Proxy).
Вопрос: как лучше всего реализовать такой TCP-сервер (язык, библиотеки, примеры), чтобы не городить много велосипедов?
Несформированные идеи как попытка симбиоза быстрого гугления и имеющихся навыков:
— написать свой TCP-сервер (Erlang?), начиная с синхронных/асинхронных сокетов, многопоточности и проч.
— или написать модуль для Apache? (плохо предтавляю как это выглядит, да и вряд ли подойдет)
— свой протокол взаимодействия между клиентом и сервером на основе JSON?
— использовать STUNT для обхода NAT-ов?
— использовать SOCKS для прохода TCP-потока через Proxy?
То есть при такой конфигурации полнодуплексное соединение вполне себе будет работать, и только если бы сервер находился за NAT пришлось бы подключать NAT traversal? То есть NAT traversal (STUN и проч.) актуальна лишь для p2p-сетей?
Ну, думаю вы сами ответили на свой вопрос — erlang лично мне кажется лучшим выходом. Вот только велосипед писать врядли стоит — возьмите какой нить yaws (думаю, с http вам проще всего будет — yaws со стороны сервера и кучи библиотек — для андроида и вовсе встроены — для клиента).
Какой протокол — не столь существенно, хотя наверное какой нить из бинарных был б поэффективней. Тем более у эрланга неплохо с обработкой бинарных данных. Нечто вроде rest-а думаю тут будет лучше всего.
NAT transversal для сервера с белым IP вовсе нафиг не нужен. Вот если у вас сервер находился за Nat-ом сам — тогда да. Вы верно заметили — это всё больше для p2p актуальней.
А вот насчёт шифровки… Да, наверное можно и ssl прикрутить, но рекомендую TLS v2 и старше (версии младше и версии ssl не так давно поломали).
Насчёт прокси вообще не понял. Стандартные механизмы запросов со стороны андроида того же более чем достаточны имхо для обработок всяких прокси. Оставьте это дело системе пользователя, не лезьте в это.
Да, конечно, это не полный дуплекс, но я не представляю, что за задачу вам реализовать надо, что полудуплекса не хватит. Хотя при желании можно и из этого полный дуплекс сделать, правда немного костылясто.
Ага, ага. Спасибо, теперь более-менее прочувствовал структурность. Вот только, насколько я знаю, http не имеет «встроенной» возможности держать соединение, и разного рода HTTP-сервера тут не подойдут. Вы имеете ввиду использовать HTTP в качестве транспорта моего собственного протокола (rest-подобного)? Но при возникновении асинхронного события на сервере он не сможет сразу оповестить клиента, если будет использоваться HTTP (то есть это решается через разного рода web-сокеты и Comet-ы). Я думал всё как-то сразу всё по TCP через сокеты пересылать (по своему протоколу), не задействуя HTTP…
Задача такая — на сервере в БД происходит UPDATE таблицы, триггер сообщает об этом серверу, сервер должен сразу оповестить клиента о новых данных (или хотя бы о факте появления новых данных). Можно, конечно, опрашивать по таймеру, но это, говорят, не выход, особенно если много клиентов.
Вот именно об этих костылях я и говорил когда говорил про полнодуплексность.) Учтите такую вещь — http пустят 99% проксиков. Ваш — это как посмотреть… Ну и в плане реализации помоему лучше привинтить всякий long pooling и иные кометообразные костыли, чем заморачиваться с прямой работой с советами.
Собственно в плане вашей структуры. Клиенты подключаются к вашему серверу в long pooling режиме и держат коннект открытым (обновляя скажем ежеминутно). Если хотят чего то обновить открывают второй коннект к вашему серверу, пересылают данные. Сервер видит что чтото обновилось и рраз — по первому коннекту весело пересылает данные. Коннект закрывается, клиент переподключает первый коннект.
Тут ещё проблема в том, что эти самые кометообразные костыли не имеют толковых реализаций для неJavaScript-а. По правде, я не знаю приложений, в котором применялись бы comet или web-sockets, кроме браузеров. Ну и смущает сама костыльная природа comet-ов, да и веб-сокеты никак не доделают.
С терминологией дуплексов что-то я напутал. Тут хватит и полудуплекса, то есть нет необходимости в прям одновременной передаче данных, но есть необходимость в способности сервера к асинхронному оповещению клиентов.
Дефакто Комет — это не более, чем два соединения, одно из которых long pooling, а второе — устанавливается в случае необходимости для передачи Инфу от клиента к серверу. Их при желании можно и вручную на уровне советов прокинуть, но зачем? ) принцип в том, что javascript открывает два этих коннекта с помощью ajax. Никакой разницы не будет, если вы их же откроете напрямую, без ajax-а — серверу в общем случае пофиг, ajax к нему присосался или прямой коннект (если вы только проверку жестко не захардкодили). Реализация на сервеиной стороне вообще никак отличаться не будет.