|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
Привет. Мне надо написать TCP/SSL server на любом языке, который бы держал около 10к одновременных долгоживущих подключений (онлайн-игра). Сервер - 4x3.80GhzXeonE5-1620, 65536MBRAMDDR3. Я написал по примерам в сети небольшой сервер с использованием TcpListener, TcpClient, Thread. Все работает как надо, держит несколько клиентов, в случае необработанных ошибок прибивает только одно соединение, вроде все хорошо, даже пашет SSL, но код выглядит через-чур просто. Из-за чего у меня появился страх, который я пока не знаю как развеять Итак вопросы. 1) Какие есть материалы в сети, о том как писать подобные сервера? 2) Кто может помочь с написанием высокостабильного сервера (есть готовый протокол) на любом адекватном языке (c#\qt c++) за деньги или советом. Если чем-то поможет, могу показать код. Может потыкаете носом в проблемы. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 12:30 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamon, 1) Зачем для игры SSL? Какие такие секретные данные он защищает? 2) ИМХО по ощущениям 10к SSL коннектов ваш сервер не выдержит. 3) Давайте описание протокола + код. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 14:10 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamonСервер - 4x3.80GhzXeonE5-1620, 65536MBRAMDDR3. . а сделать 2 сервера религия не позволят? сразу будет 5к а не 10к и да , зачем ССЛ? ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 14:22 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
Клиент написан, и меняться ради нашего сервера не будет (ну ведь понятно, что клиент не наш, а вот сервер хотим свой )) ) Поэтому такое требование. Насчет двух серверов, я не знаю, но вроде до 6 серверов вполне можно. Требование взято с потолка. кривокод, в зипке: ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 15:27 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamon, честно не смотрел весь код, но я так понимаю каждому соединению свой поток? Код: c# 1.
Т.е. при максимальной загрузке у вас будет 10 000 потоков? Я сомневаюсь, что такое будет работать... ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 15:41 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamon, 1) Требование полного SSL - это чушь. Но примем за факт. 2) 30 000 коннектов сервер не потянет, нужно балансирование. Смотрите nginx и HAproxy 3) Код, прости господи, хоть и простой, но говеный. Самая главная претензия - зачем на каждого клиента создавать свой поток? У вас из 30 000. Переключения контекста забьют всю производительность. А ведь еще SSL есть. В общем, асинхронность + TPL (Task и иже с ним). Про async/await не скажу, не тестил. Далее, зачем использовать синхронную версию AcceptTcpClient? Обработка сообщений у вас стремная, нет типов. Или они все у вас одного типа? Обработка исключений отсутствует. Если есть общие данные для всех клиентов, они не кэшируются. Откуда же данные берутся? Это так, что в глаза сходу бросилось. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 15:42 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
Arm79, про асинхронность подпишусь. Вроде начиная с TPL там делать это совсем легко. А почему думаю сервер 30к соединений не потянет? В мою бытность было все через BeginXXX,ENDXXX и тд. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 15:47 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
netivanJustOxlamon, честно не смотрел весь код, но я так понимаю каждому соединению свой поток? Код: c# 1.
Т.е. при максимальной загрузке у вас будет 10 000 потоков? Я сомневаюсь, что такое будет работать... Я тоже сомневаюсь что сработает, поэтому и спрашиваю тут. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 15:47 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
Arm79, Про SSL обсудили, это требование клиентской программы, на которую мы не влияем. Поэтому можно смириться. Гут, со всем остальным согласен. Например, если бы вам дали такую задачу, сколько времени бы она заняла при бюджете в 90к рублей? Пакеты такие говенные потому, что они все одинаковые. (хотя я бы сделал один базовый, и кучу от него наследовались, бы, ну и все такое по умному, но... ) Общих данных нету. Кешировать нечего. Про качество кода, это лучше не в этом куске обсуждать. Пример на коленке написан, и похож на кусок сами знаете чего. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 15:55 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
netivanА почему думаю сервер 30к соединений не потянет? Это мое предположение. Не потому, что 30000 - это жутко много для сервера. А потому что будет большая вычислительная нагрузка на шифрование данных. Там, хоть и и используются симметричные шифры, все равно прилично нагружаются. А скорость, как я понимаю, для онлайн-игры важна ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 15:55 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamonесли бы вам дали такую задачу, сколько времени бы она заняла при бюджете в 90к рублей? Мне? При условии наличия полного ТЗ и доступа к тестовому контуру? Неделя, не более. Но я человек занятой, и фрилансить могу не более 2-3 часов в день :-) Так что примерно месяц. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 15:57 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
В общем как я понял, сильно желательно переписать с использованием асинхронных сокетов. Ладно, куда копать? Где есть живой пример SSL+ Async Socket? Кто готов взяться за этот кусок, если хочется денег то 90к в принципе ждут. В идеале я бы хотел получить DLL с подобными интерфейсами: (ТЗ вполне можно составить совместно с исполнителем, чтобы не было никаких фантазий) Вкратце выглядеть может все так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 16:06 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
Вот еще замечания: 1) У вас класс Пакет выполняет сразу несколько функций. И парсинг, и работу с потоком. Нужно разделить его на непосредственно класс Пакет (с бизнес-логикой при необходимости) и класс для работы с потоком. 2) При записи в поток зачем то работа на уровне байтов. Не надо совмещать парсинг и отправку данных, заранее подготовьте пакет и разом пишите его в поток. 3) Побайтное чтение из потока тоже не вдохновляет, в первую очередь своей скоростью. И я не уверен, что вы не напутали с кодировками. У вас и 28591, и utf-8, и неявно Unicode (при добавлении символа в StringBuilder) (2 и 3 - сделали бы пользовательскую сериализацию своего объекта) 4) Нет очистки sslStream. TcpClient вы закрываете, а его поток - нет 5) Зачем лочить WriteLocker? У вас же один поток на одного клиента. ИМХО лишняя синхронизация ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 16:09 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamonКто готов взяться за этот кусок, если хочется денег то 90к в принципе ждут. Arm79Но я человек занятой, и фрилансить могу не более 2-3 часов в день :-) Так что примерно месяц Если устроят растянутые сроки, welcome Ну или пишите сами, здесь подскажут, как правильно. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 16:13 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
Arm79Вот еще замечания: 1) У вас класс Пакет выполняет сразу несколько функций. И парсинг, и работу с потоком. Нужно разделить его на непосредственно класс Пакет (с бизнес-логикой при необходимости) и класс для работы с потоком. 2) При записи в поток зачем то работа на уровне байтов. Не надо совмещать парсинг и отправку данных, заранее подготовьте пакет и разом пишите его в поток. 3) Побайтное чтение из потока тоже не вдохновляет, в первую очередь своей скоростью. И я не уверен, что вы не напутали с кодировками. У вас и 28591, и utf-8, и неявно Unicode (при добавлении символа в StringBuilder) (2 и 3 - сделали бы пользовательскую сериализацию своего объекта) 4) Нет очистки sslStream. TcpClient вы закрываете, а его поток - нет 5) Зачем лочить WriteLocker? У вас же один поток на одного клиента. ИМХО лишняя синхронизация 1, 2, 3) Тут весь код набросан по-быстрому, так сказать PoC. Поэтому довольно нелогичный. Пакет заменить на собственно пакет с данными и скажем что-то вроде ParserStream. Кодировка везде должна быть одна Latin-1. Остальное там эксперименты ) 4) ну это все туда же ) 5) из-за того что сервер из другого потока может что-то сообщать клиенту, например команду на выход присунуть или сообщение. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 16:24 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
Arm79JustOxlamonКто готов взяться за этот кусок, если хочется денег то 90к в принципе ждут. Arm79Но я человек занятой, и фрилансить могу не более 2-3 часов в день :-) Так что примерно месяц Если устроят растянутые сроки, welcome Ну или пишите сами, здесь подскажут, как правильно. Буду думать, месяц действительно много, но сам я точно писать не буду. Так что буду искать. Ну и по-тихому писать основу для ТЗ. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 16:25 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamon, выложите Тз своими словами, чтобы хотя бы понимать приблизительно. Может быть там дело на выходные, а может и месяца мало :). ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 16:35 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
netivanМожет быть там дело на выходные да ну :-) Сервер под 10k клиентов должен быть обложен тестами по максимуму :-) Толку от него, если он будет постоянно падать. Там же несколько сценариев нужно предусмотреть, включая принудительный рестарт с сохранением неотправленных сообщений. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 16:42 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
netivanJustOxlamon, выложите Тз своими словами, чтобы хотя бы понимать приблизительно. Может быть там дело на выходные, а может и месяца мало :). Звучит примерно так: Написать TCP - сервер (теперь уже точно на C#) со следующими характеристиками: 1) Поддержка SSL (ну надо, так надо... ) 2) Наиболее производительный (в мечтах 10к на одном сервере, но любое адекватное число также устроит) 3) Клиенты должны быть изолированы по возможности друг от друга. Поясню, в итоге это будет сервер где хостится много игр с одним протоколом, каждую игру будут писать разные люди со своими тараканами, поэтому из-за ошибки у одного клиента и в одной игре сервер не должен умирать и не должен убивать других игроков. В потоковом варианте, это в принципе было по умолчанию и меня сильно устраивало такой халявой. 4) Ход работы примерно такой: 1. Запускаем сервер. 2. *Внутренний менеджер загружает игровые DLL инициализирует общие данные, коннектит к бд, подгружает оттуда что надо 3. Запускается tcp-сервер на определенном порту, начинается прием. 4. Коннектится клиент, создается с ним SSL - поток 5. Клиент шлет данные, мы его авторизуем через БД* 6. Клиент выбирает игру, играет, каждый ход фиксируется в БД* 7. Клиент закрывает игру, мы подчищаем за ним. Программировать нужно ТОЛЬКО работу с сетью (т.е. все то что без * ). Т.е. примерно то что у меня в говнозипке сидит, только это и надо. Только грамотно и с учетом требований. Понятно, что есть много дополнительных хотелок. Но они обсуждаются, фиксируются в начале работы. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 16:52 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamon, Мало. 1) Как планируется обрабатывать ошибки с клиента? Может, неверный протокол. Нужно ли срубать или ожидать ввода правильных данных? 2) Как планируется защищаться от DDoS? 3) Как внутренний игровой менеджер взаимодействует с транспортным сервером? Если все в одном процессе, то надежность сервера в том числе зависит от этого менеджера. Упадет он - упадет все. Если это разные процессы, то как они будут взаимодействовать, и каков алгоритм действий при падении менеджера? 4) У вас база то выдержит обращения десятков тысяч клиентов (с учетом не одной игры)? Нет никакого кэша? ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 17:06 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamon, теперь мне не очень понятен суть клиента и сервера. Сервер - это хрень, которая слушает TCP порты и отвечает на них в зависиомсти от клиента (видимо ответ берется из базы), или как? Один клиент - один порт, или один порт- Х клиентов (судя по примеру)... я бы вообще сделал через WCF это надо. Мне кажется в итоге и получится некий велосипед... А задача на самом деле очень интересная и как правильно заметил выше Арм, оч много можно всего накрутить. Вопрос именно в требовании. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 17:15 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
Arm79JustOxlamon, Мало. 1) Как планируется обрабатывать ошибки с клиента? Может, неверный протокол. Нужно ли срубать или ожидать ввода правильных данных? 2) Как планируется защищаться от DDoS? 3) Как внутренний игровой менеджер взаимодействует с транспортным сервером? Если все в одном процессе, то надежность сервера в том числе зависит от этого менеджера. Упадет он - упадет все. Если это разные процессы, то как они будут взаимодействовать, и каков алгоритм действий при падении менеджера? 4) У вас база то выдержит обращения десятков тысяч клиентов (с учетом не одной игры)? Нет никакого кэша? Любая ошибка клиента - отключение клиента. Клиент отлажен и априори безгрешен (я знаю-знаю, но такова политика) От ддоса планируем лежать намертво. Это не проблема сервера. Игровой манагер сейчас это список типов подобного толка: dictionary<string, type> при старте игры ищется игра, и создается, потом контроль передается ей, через интерфейс - OnPacket( Player pl, Paket pk, DataSource ds ); и все что внутри нее, работает как ударит моча в голову разработчика, на текущий момент при ексепшонах, падает коннект и клиент убивается - это правильно. так надо. база держит гораздо больше, она там расшарена, кешируется, разделена по серверам и т.п. (ну хоть где-то грамотно) ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 17:25 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
netivanJustOxlamon, теперь мне не очень понятен суть клиента и сервера. Сервер - это хрень, которая слушает TCP порты и отвечает на них в зависиомсти от клиента (видимо ответ берется из базы), или как? Один клиент - один порт, или один порт- Х клиентов (судя по примеру)... я бы вообще сделал через WCF это надо. Мне кажется в итоге и получится некий велосипед... А задача на самом деле очень интересная и как правильно заметил выше Арм, оч много можно всего накрутить. Вопрос именно в требовании. Я бы тоже писал на WCF\tcp.net и был бы счастлив т.к. строгая типизация, норм трафик и ваще полная няшка. Но тут на клиент мы не влияем никак. Поэтому протокол уже есть и фиксирован. Много клиентов, один сервер, слушает один порт. Самих серверов может быть до 6 штук. Действительно требуется только примерно вот это: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
+/- детали НЕ усложняющие разработку. Которые будут оговорены ВНАЧАЛЕ во время написания совместного ТЗ, возможно по скайпцу. Остальное мы наговнокодим сами ) ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 17:30 |
|
TCP\SSL-Server на C#
|
|||
---|---|---|---|
#18+
JustOxlamon, то есть: 1) Априори SSL на все без какой-либо валидации сертификата (нет защиты от подмены) 2) Нет защиты от DDOS 3) Нет обработки ошибок клиентского протокола. Чуть что - клиент, давай до свидания 4) транспортный сервер должен поддерживать плагинную структуру (хотя бы на уровне IoC) С 4 пунктом неясно, я так и не понял, транспортный сервер и менеджер - это один процесс или несколько? Да и интерфейс OnPacket непонятно описан. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2013, 17:32 |
|
|
start [/forum/topic.php?fid=20&msg=38468837&tid=1402226]: |
0ms |
get settings: |
11ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
40ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
68ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 168ms |
0 / 0 |