2009-04-29 18 views
11

Szukałem dobrej ogólnej definicji binarnego protokołu sieciowego, aby umożliwić pisanie serwerów i klientów gier w czasie rzeczywistym (np. World Of Warcraft lub Quake III). wiele języków (np. serwer Java backend i klient frontonu iPhone napisany w Objective-C i Cocoa).Dostępne języki definicji protokołów sieciowych gier sieciowych i generowania kodu

Chcę obsługiwać klientów Java Flash, klientów iPhone i klientów C# w systemie Windows (i klientów XNA na konsoli Xbox).

Szukam sposobu na wydajne wysyłanie/odbieranie wiadomości przez połączenie strumienia TCP/IP lub UDP. Nie szukam czegoś, co można przesłać za pośrednictwem usługi sieciowej HTTP, takiej jak JSON lub obiekty z odwzorowaniem XML. Chociaż binarny protokół usługi sieciowej Hessian jest bardzo interesującym rozwiązaniem, to potrzebuję formatu protokołu sieciowego i podstawowej implementacji klient/serwer, która pozwoli klientowi połączyć się z serwerem i wysłać dowolną wiadomość w zdefiniowanym protokole i odebrać dowolną wiadomość. protokół bez konieczności wiązania z pewnym punktem końcowym RPC. Chcę ogólny strumień dowolnej wiadomości w protokole przychodzącym i wychodzącym. Jest tak, że mogę obsługiwać takie rzeczy, jak serwer wysyłający wszystkich klientów pozycje różnych podmiotów w grze co 100 milisekund.

+0

Co masz na myśli przez to stwierdzenie: "bez konieczności wiązania się z jakimś punktem końcowym RPC" – grieve

+0

Przez "bez wiązania z jakimś punktem końcowym RPC", mam na myśli po stronie serwera, nie chcę, aby tylko być w stanie zaakceptować żądania RPC Chcę, aby była w stanie zainicjować odwrotność wnioski do klientów i otrzymywać wiadomości. Zasadniczo nie chcę konfiguracji klienta/serwera RPC, chcę strumienia wiadomości klienta i strumienia wiadomości serwera, w którym wiadomości są zdefiniowane w niektórych IDL, które mogą generować powiązania kodu dla klientów/serwerów w wielu językach. – Dougnukem

+0

Rozumiem, co mówisz teraz. Dzięki za wytłumaczenie. – grieve

Odpowiedz

14

protokołu sieciowego ramy znalazłem są następujące:

  1. Google's Protocol Buffer - ale brakuje wsparcia dla takich rzeczy jak wysyłanie/odbieranie dowolnych wiadomości z danego protokołu.
  2. - interesująca opcja, ale jest ukierunkowana głównie na RPC zamiast ogólnych połączeń typu klient/serwer, w których klient lub serwer może wysyłać wiadomości w dowolnym momencie, a nie tylko w odpowiedzi na żądanie klienta RPC.
  3. Raknet Multiplayer - Raknet zapewnia pełną bibliotekę sieciowy multiplayer (to nic nie kosztuje dla rozwoju indie z dochodów pod $ 250k)

UPDATE: OculusVR Acquired RakNet a jej wolny/OpenSource teraz. U można go znaleźć na Github

  1. Hessian Binary Web Service Protocol - to internetowy protokół HTTP usługa binarny, jest dobrze nadaje się do wysyłania danych binarnych bez konieczności przedłużenia protokołu z załącznikami.

Raknet zapewnia dobrą bibliotekę gier wieloosobowych zorientowaną na grę/symulację.

Apache Thrift i bufory protokołu Google wydają się być najprostszym podejściem do używania w architekturze klient/serwer sieciowej protokołu gry.

Wygląda na to, że Hessian świetnie się nadaje, jeśli chce się utworzyć internetowy serwer gry z klientem Java lub Flash przy użyciu technologii przesyłania danych typu serwera, takiej jak COMET. Hessian może dostarczyć naprawdę interesującego sposobu na obsługę gier w czasie rzeczywistym w Internecie, a nawet być w stanie hostować je w sieciowych rozwiązaniach VM, takich jak silnik aplikacji Google czy EC2 firmy Amazon.

Jest jakaś dyskusja na temat używania różnych ram definicji protokół do gier i innych zastosowań:

+1

Osobiście najpierw przyjrzę się buforom protokołów, jako że wydaje się, że obecnie obsługiwane jest kilka języków. Nie musisz używać RPC do wysyłania ProtoBufów, więc możesz łatwo przesyłać je strumieniowo przez gniazdo, o ile najpierw określisz długość (np. Length | protobuf | length | protobuf ...). Jedynym minusem jest to, że wszystkie wiadomości muszą być zdefiniowane jako głowa czasu, co jest prawdopodobnie dobrą rzeczą. – mattkemp

0

Chcę powtórzyć sugestię Billa K. Nie jest trudno przetworzyć własny protokół.

Po stronie iPhone'a spójrz na AsyncSocket, który obsługuje wbudowane pakiety oparte na ogranicznikach TCP i nie jest trudno zbudować rozwiązanie wykorzystujące nagłówki pakietów.

Jeśli szybko chcesz mieć serwer testowy do gry z AsyncSocket na iPhonie, możesz spojrzeć na Naga (dla części serwera Java), która ma gotowe elementy zarówno dla pakietów opartych na delimiterach, jak i pakietów z nagłówkami. Naga została częściowo napisana z myślą o grach sieciowych.

0

Nie zgadzam się z tym, że "stosuj proste podejście z ograniczonymi łańcuchami": pytanie brzmi, jaka dokładnie byłaby korzyść? Jak napisać i zachować więcej kodu? Jedyne powody, dla których mogłem zobaczyć, to brak obsługi narzędzi (pisanie na jakiejś dziwnej platformie) lub konkretne (bardzo) twarde ograniczenia wydajności lub ograniczenia rozmiaru wiadomości. Czasami naprawdę chcesz napisać format - to dobrze, ale musi to być wyraźny powód.

W zależności od konkretnych potrzeb sugerowałbym, biorąc pod uwagę JSON, ponieważ może on czytać i pisać dowolne wiadomości; ma dobre obiekty wiążące dla Javy (podobnie jak xml), jest łatwiejszy do odczytania niż formaty binarne i wszędzie jest "wystarczająco dobry" dla wielu przypadków użycia.

Jeśli rozmiar wiadomości jest bardzo ważny, Protobuf może działać dobrze - podczas gdy jego rozmiar nie zawsze jest tak mały jak gzipowane alternatywy (gzip + xml, gzip + json kompresuje się bardzo dobrze), zwykle jest blisko.

+0

@StaxMan, całkowicie zgadzam się, że napisanie własnego niestandardowego protokołu jest stratą czasu i po prostu tworzy utrzymanie koszmaru podczas próby obsługi wielu języków lub rozszerzania go. JSON i gzip + json mogą być przyzwoitą opcją, szczególnie do pisania usług internetowych, ale myślę raczej o sytuacjach, w których nie potrzebuję lub nie chcę formatu tekstowego (takiego jak usługa sieciowa), ale w sytuacjach, w których potrzebujesz szybkiego protokołu binarnego, takiego jak budowanie serwera gry (takiego jak World of Warcraft lub Quake III), w którym to przypadku parsowanie tekstu JSON do natywnego obiektu/struktury byłoby zabronione. – Dougnukem

0

ASN.1 wpisuje się w definicję "dobrego ogólnego schematu definicji protokołów sieciowych". Jest również standaryzowany przez ITU-T, więc istnieje wiele istniejących narzędzi i bibliotek dla różnych języków.

Kodowanie DER jest odpowiednie do wydajnej komunikacji sieciowej, kodowania XER do odczytu trwałego (czytelnego dla człowieka).

0

Dlaczego nie zaimplementować bezpośrednio UDP? Twoje pytanie głównie wspomina, czego nie chcesz .. Jakie dalsze formy abstrahowania do chcesz na górze UDP? Pobierz kod źródłowy Quake III i zobacz, jak dopasowują aktualizacje gry do UDP?

Protokół IP został zaprojektowany, aby obsługiwać wiele urządzeń/systemów operacyjnych w jednolity sposób, czy nie o to prosisz? Jaki protokół ma implementacje w szerokim zakresie systemów, hmm, IP może?

+0

Protokół, który omawiam, nie jest dokładnie tym samym protokołem transportu niskiego poziomu, który implementuje protokół UDP lub TCP. Mówię o protokole poziomu aplikacji. Z tego, co przeczytałem o modelu sieciowym Quake III (http://www.tilion.org.uk/Games/Quake_3/Network_Protocol), implementują bardzo prosty podzestaw poleceń gry, które mają być wysyłane do każdego klienta. Kod do odbierania tych wiadomości przez sieć jest napisany w kliencie/serwerze C, szukam sposobu na zautomatyzowanie tego generowania kodu, dzięki czemu mogę utworzyć klienta/serwery w innych językach, takich jak Java/Objective-c, używając tej samej aplikacji protokół. – Dougnukem

1

Jeśli pójdziesz drogą pisania własnego protokołu, możesz przeczytać odpowiedź, którą zamieściłem: here.

Podsumowując, omawia, o czym należy pomyśleć przy pisaniu protokołu, oraz podaje kilka trików dotyczących wersjonowania i zachowania zgodności wstecznej i przyszłej.

1

Jeśli jesteś naprawdę zaniepokojony wielu platformach i język, należy wziąć pod uwagę endian problemów. Protokół binarny zaprojektowany do tego celu musi wykorzystywać kolejność sieć-bajt, więc potrzebuje niestandardowych funkcji serializacji danych; nie możesz po prostu ślepo przesuwać C-struktur do buforów sieciowych.

Powszechnym rozwiązaniem tego problemu w firmach branży gier jest posiadanie języka opisu protokołu lub specyfikacji w prostym formacie, takim jak XML lub python lub lua, a następnie generowanie kodu dla każdego języka docelowego, który generuje klasy pakietów zarówno o strukturze danych, jak i serializacja. Ta specyfikacja mogłaby korzystać z systemu typów, który zaczyna się od typów podstawowych, a następnie rozciąga się na typy specyficzne dla gry z informacjami semantycznymi, wyliczeniami lub bardziej złożonymi strukturami. Na przykład plik danych może wyglądać tak:

Attack = { 
    source = 'objectId', 
    target = 'objectId', 
    weapon = 'weapon::WEAP_MAIN', 
    seed = 'int' 
} 

Kod ten może generować jak:

#define PT_ATTACK 10002 

class PacketAttack : public Packet { 
    public: 
    PacketAttack() : m_packetType(PacketAttack::s_packetType) {} 

    ObjectId m_source; 
    ObjectId m_target; 
    WeaponType m_weapon; 
    int m_seed; 

    bool Write(Stream* outStream) { 
     Packet::Write(outStream); 
     outStream << m_source; 
     outStream << m_target; 
     outStream << m_weapon 
     outStream << m_seed; 
    } 

    bool Read(Stream* inStream); 

static const int s_packetType; 
}; 

To wymaga trochę więcej infrastrukturę .. strumienie, klas podstawowych pakietów, sejf funkcje serializacji ..