2012-03-19 11 views
9

Trochę kontekstu: piszę grę klient/serwer w Scala (pierwsza osoba), gdzie klient musi wysłać intencje ruchu na serwer kilkadziesiąt razy na sekundę, a serwer wysyła stany jednostek z powrotem, również w czasie rzeczywistym. Istnieje fizyczna symulacja tych elementów za pomocą JBullet zarówno na kliencie (dla płynności graficznej), jak i po stronie serwera. Za każdym razem, gdy klient otrzymuje aktualizacje z serwera, zastępuje swoje stany lokalne tymi, które wysłał serwer. Oczywiście może istnieć wielu klientów na tym samym serwerze w danym momencie. Krótko mówiąc, w tej aplikacji często dochodzi do komunikacji z małymi pakietami.Scala Case Classes vs. Bufory protokołów z Akka przez sieć

W tej chwili używam aktorów Akki do naiwnego wysyłania klas scen Scala przez sieć do serwera iz powrotem. Oto przykład:

sealed trait PlayerMessage 
case class PlayerMove(dir: Vector3, run: Boolean) extends PlayerMessage 
// more case classes... 

Następnie na kliencie:

server ! PlayerMove(dir, run) 

Na serwerze:

def receive = { 
    case pm: PlayerMessage => pm match { 
    case p @ PlayerMove(dir, run) => 
     // Move the player 
     world.playerMove(dir,run) 

     // More case tests.. 
    } 

    // Send back entity states (this in fact occurs elsewhere, asynchronously) 
    world.entities.foreach(ent => client ! ent.state())) 

    // More message testing ... 
    case _ => // ignore 
} 

Gdzie ent.state zwraca EntityState:

case class BulletState(pos: Vector3, quat: Vector4, lin: Vector3, ang: Vector3) 

sealed trait EntityState 
case class EntityStatePlayer(id: Int, bullet: BulletState) extends EntityState 
// more case classes... 

Wszystko działa całkiem nieźle, ale jak widać istnieje wiele klas przypadków, czasami zawierające inne klasy przypadków i mnóstwo testów przypadku zarówno na kliencie, jak i na serwerze.

  • Jak zmniejszyć zarówno rozmiar pakietu, jak i obciążenie na podstawie serializacji, deserializacji i dopasowania?
  • Używanie Protobuf zamiast klas przypadków wycina tłuszcz z pakietów mojej aplikacji?
  • Czy szukam niewłaściwego miejsca na ulepszenie tego protokołu sieciowego?

Odpowiedz

7

Domyślnie Akka używa serializacji Java lub Google Protobufs (patrz here i here). Możesz zdefiniować własne serializery, jeśli myślisz, że możesz zakodować coś, co jest bardziej zoptymalizowane dla twojej aplikacji.

Jeśli chcesz zoptymalizować swój protokół sieciowy, będziesz musiał przebić się your favorite network sniffer, aby dowiedzieć się, co faktycznie jest wysyłane tam iz powrotem. Wtedy możesz lepiej zdecydować, co robić.

Ogólnie rzecz biorąc, prawdopodobnie można ręcznie utworzyć lepiej zoptymalizowany protokół sieciowy, ale jest on bardziej podatny na złamanie, gdy trzeba wprowadzić zmiany (chyba że masz dużo doświadczenia w pisaniu protokołów sieciowych) .

+0

Przeczytałem już te, ale nadal nie jestem pewien, czy klasa przypadku jest serializowana jako Google Protobuf, czy nie; Nie zgaduję. Dlatego chciałbym dowiedzieć się, co mogę uzyskać, przekształcając moje klasy przypadków w Protobufs, jeśli w ogóle warto. Napowietrzne wokół nich może usunąć wszelkie rzeczywiste korzyści; Wireshark może pomóc na później. – gsimard

+0

Jeśli masz 'proto =" akka.serialization.ProtobufSerializer "' w twojej konfiguracji, Protobuf jest używany do serializacji. – leedm777

+4

Przeczytaj odpowiednią sekcję dokumentacji: http://doc.akka.io/docs/akka/2.0/scala/serialization.html –