2016-07-11 18 views
2

Ich bin ein selbstdefinierte TCP-Protokoll mit hereIst es möglich, auf scalas akka ByteString ein Muster zu finden?

class SimplisticHandler extends Actor { 
    import Tcp._ 
    def receive = { 
    case Received(data) => sender() ! Write(data) 
    case PeerClosed  => context stop self 
    } 
} 

Unter Received(data) Annahme den SimplisticHandler in TCP-Server Beispiel akka's tcp extention

Implementierung ist es möglich, auf der Byte-Sequenz Muster überein? Wie ich es verstehe, muss ein Extraktor definiert sein, damit der Mustervergleich funktioniert. Es scheint keine unapply wie in der documentation definiert zu sein.

Ich möchte so etwas wie:

def receive = { 
    case Received(data) => 
     val worker = getSomeWorkerActor 
     worker ! data 
    } 

Dann bei Kindern Arbeiter:

private[this] def commandA(cmd: ByteString) = println(cmd) 
def receive = { 
    // [warn] foo.scala:55: abstract type pattern Coll is unchecked since it is eliminated by erasure 
    // [error] foo.scala:55: type mismatch; 
    // [error] found : scala.collection.SeqLike[T,Coll] 
    // [error] required: akka.util.ByteString 
    case 0x01 +: command => commandA(command) 
    case 0x02 +: 0x03 +: command => commandB(command) 
} 

während command als ByteString halten. Wenn das so ist, wie? Oder was wäre eine empfohlene Alternative? Ich möchte vermeiden, in String zu dekodieren, dann gegen String zu vergleichen, wenn das möglich ist.

scala 2.11.8, 2.4.7 akka

+0

Versuchen Sie nur, auf dem ersten Byte übereinzustimmen? –

+0

@ChrisMartin Idealerweise würde zu beliebiger Anzahl von Bytes passen – user2829759

+2

Es scheint aus der Box funktionieren, wenn Sie dies verwenden: 'case 0x01 +: command => ...'. – devkat

Antwort

3

in einem Muster konstruieren übereinstimmt, wird der Typ des Musters von der rechten Seite des Gehäuses Klausel nicht infered, siehe auch Pattern Matching Expressions. Daher wird der Parametertyp von commandA und commandB nicht berücksichtigt. Sie müssen auf ByteString zuerst übereinstimmen:

def receive = { 
    case b: ByteString => b match { 
    case 0x01 +: command => commandA(command) 
    case 0x02 +: 0x03 +: command => commandB(command) 
    } 
}