2016-07-15 7 views
0

Netty 4.1.2.FinalNetty 4: Referenzzähler in gewickelten Puffern

Ich verwende Unpooled.wrappedBuffer Verfahren mehr als ein ByteBuf s einzuwickeln, API doc ist here.

public static ByteBuf wrappedBuffer(ByteBuf... buffers) 

Der Doc sagt

Referenzzählung Besitz aller Variablen dieser Methode übertragen wird.

Ich aktualisiere die Frage, damit es klarer ist.

Ich muss mehr als eine ByteBuf s an mehrere Verbindungen gleichzeitig senden. Ich kann ChannelGroup nicht verwenden, da einige der Clients im Long-Polling-Modus arbeiten, was bedeutet, dass die Antwort in der nächsten Anfrage gesendet werden muss, deren Kanal in diesem Moment nicht bereit ist.

Daher habe ich die folgende Datenstruktur, die die angeschlossenen Kanäle

private static final ConcurrentHashMap<String, Channel> channels 
    = new ConcurrentHashMap<String, Channel>(); 

Shops und Ich habe ein Verfahren mit den ByteBuf zu den Kanälen

public static void broadcast(final long registrationID, final ByteBuf [] buffers){ 
    final ByteBuf wrappedBuf = Unpooled.wrappedBuffer(buffers); 
    for(Map.Entry<String, Channel> entry : channels.entrySet()){ 
    final Channel channel = entry.getValue(); 
    if(channel != null){ 
     wrappedBuf.retain(); 

     boolean isLongPooling = channel.attr(TYPE).get(); 
     if(isLongPooling) 
      Reply.send(channel, wrappedBuf); // add into a queue which will be pulled by client in next request 
     else 
      channel.writeAndFlush(wrappedBuf); // real time client , send in current channel 
    } 
    } 
    wrappedBuf.release(); 
} 

Das Problem auszustrahlen ist, dass: Wenn ich haben mehr als einen Echtzeit-Client verbunden, nur einer von ihnen empfängt die Antwort, selbst wenn alle von ihnen geschrieben sind.

Es scheint, dass es ein Problem ist, das durch Referenzzählung verursacht wird?

Danke

+0

Der Grund ist nicht Referenzzählung, es wird durch einen Handle verursacht ändert die 'ByteBuf'. Daher erhält nur die erste Verbindung. Die Lösung besteht darin, nach ByteBuf 'asReadOnly()' hinzuzufügen. –

Antwort

1

Nein ... es bedeutet, dass die Sie benötigen Release() aufzurufen, auf dem zurückgegebenen Puffer.

+0

Wenn ich 'release()' aufrufen muss, bedeutet dies, dass der Eingang 'ByteBuf's beibehalten wird? Sonst, warum würde ich 'release()' aufrufen müssen, wenn keine Änderung der Referenz zählt? –

+1

Wenn Sie Puffer umbrechen, sollten Sie release() für den neu zurückgegebenen Puffer und nicht für die Puffer, die Sie gerade umschlossen haben, aufrufen. –

+0

Von meinem Test funktioniert es nicht auf diese Weise. Wenn ich nicht "retain" des ursprünglichen "ByteBuf" aufrufen, wird "IllegalReferenceCountException" auftreten. Wenn ich 'retain' des eingepackten 'ByteBuf' aufrufen, ändert sich nicht die Referenzzahl der Unterschicht' ByteBuf'. –