2016-07-16 11 views
0

Ich habe versucht, eine Nachricht an viele Server über netty zu senden und nur Serverantwort zu löschen. Ich habe ein kleines Beispiel mit der Umsetzung vorbereitet, bitte bei unten aussehen:Netty: Problem mit dem Senden von Nachrichten an viele Server

import io.netty.bootstrap.Bootstrap; 
import io.netty.buffer.ByteBuf; 
import io.netty.buffer.Unpooled; 
import io.netty.channel.ChannelFuture; 
import io.netty.channel.ChannelInitializer; 
import io.netty.channel.ChannelOption; 
import io.netty.channel.ChannelPipeline; 
import io.netty.channel.EventLoopGroup; 
import io.netty.channel.nio.NioEventLoopGroup; 
import io.netty.channel.socket.SocketChannel; 
import io.netty.channel.socket.nio.NioSocketChannel; 
import java.util.LinkedList; 
import java.util.List; 

public class MainTest { 

    private final List<ConnectionInfo> HOSTS = new LinkedList<>(); 
    private final ByteBuf buf; 

    public MainTest() { 
     HOSTS.add(new ConnectionInfo("127.0.0.1", 10000)); 
     HOSTS.add(new ConnectionInfo("127.0.0.1", 20000)); 
     HOSTS.add(new ConnectionInfo("127.0.0.1", 30000)); 
     HOSTS.add(new ConnectionInfo("127.0.0.1", 40000)); 
     HOSTS.add(new ConnectionInfo("127.0.0.1", 50000)); 

     buf = Unpooled.buffer(100); 
     for (int i = 0; i < buf.capacity(); i ++) { 
      buf.writeByte((byte) i); 
     } 
    } 

    public static void main(String[] args) throws InterruptedException { 
     new MainTest().start(); 
    } 

    public void start() throws InterruptedException { 
     for (ConnectionInfo connectionInfo : HOSTS) { 
      // Configure the client. 
      EventLoopGroup group = new NioEventLoopGroup(); 
      try { 
       Bootstrap b = new Bootstrap(); 
       b.group(group) 
         .channel(NioSocketChannel.class) 
         .option(ChannelOption.TCP_NODELAY, true) 
         .handler(new ChannelInitializer<SocketChannel>() { 
          @Override 
          public void initChannel(SocketChannel ch) throws Exception { 
           ChannelPipeline p = ch.pipeline(); 
           //p.addLast(new LoggingHandler(LogLevel.INFO)); 
           p.addLast(new EchoClientHandler(buf.copy())); 
          } 
         }); 
       // Start the client. 
       ChannelFuture f = b.connect(connectionInfo.getHost(), connectionInfo.getPort()).sync(); 
       // Wait until the connection is closed. 
       f.channel().closeFuture().sync(); 
      } finally { 
       // Shut down the event loop to terminate all threads. 
       group.shutdownGracefully(); 
      } 
     } 
    } 

    private class ConnectionInfo { 
     private final String host; 
     private final int port; 

     public ConnectionInfo(String host, int port) { 
      this.host = host; 
      this.port = port; 
     } 

     public String getHost() { 
      return host; 
     } 

     public int getPort() { 
      return port; 
     } 
    } 
} 

und EchoClientHandler Klasse:

import io.netty.buffer.ByteBuf; 
import io.netty.channel.ChannelHandlerContext; 
import io.netty.channel.ChannelInboundHandlerAdapter; 

public class EchoClientHandler extends ChannelInboundHandlerAdapter { 

    private final ByteBuf message; 

    public EchoClientHandler(ByteBuf buf) { 
     message = buf; 
    } 

    @Override 
    public void channelActive(ChannelHandlerContext ctx) { 
     ctx.writeAndFlush(message); 
     ctx.close(); 
    } 

    @Override 
    public void channelReadComplete(ChannelHandlerContext ctx) { 
     ctx.flush(); 
    } 

    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
     cause.printStackTrace(); 
     ctx.close(); 
    } 
} 

aber wenn einige Server aus der Liste nicht verfügbar Schleife unterbrochen werden wird. Ich würde das gerne reparieren. Hast du irgendwelche Ideen dafür?

+0

Um eine Nachricht gleichzeitig an viele Geräte zu senden, sollten Sie Multicast verwenden. Die Empfänger sollten eine Multicast-Gruppe abonnieren, und der Absender sendet nur eine Nachricht an die Multicast-Gruppe. Dies ist genau das Problem, für das Multicast als Lösung konzipiert wurde. –

+0

@RonMaupin sicher, aber nicht für diesen Fall. Es ist nur ein Testbeispiel für Netty, nichts Ernstes. Aber wenn Sie einige Beispiele für die Verwendung von Multicast in Java haben, teilen Sie es bitte mit mir. –

Antwort

1

fand ich 2 Lösungen:

  1. Wrap-Code in der Schleife Klasse fädeln.
  2. Deaktivieren der Synchronisierung, wenn auf Server

Betrachten wir diese 2 Lösungen im Code verbinden.

1. Wickeln:

for (ConnectionInfo connectionInfo : HOSTS) { 
    new Thread() { 
    public void run() { 
     // Configure the client. 
     EventLoopGroup group = new NioEventLoopGroup(); 
     try { 
     Bootstrap b = new Bootstrap(); 
     // ....... etc 
     } finally { 
     // Shut down the event loop to terminate all threads. 
     group.shutdownGracefully(); 
     } 
    } 
    }.start(); 
} 

2. Deaktivieren sync (und fügen Sie einige Logging):

// Start the client. 
ChannelFuture f = b.connect(connectionInfo.getHost(), connectionInfo.getPort()); 
f.addListener(new ChannelFutureListener() { 
    @Override 
    public void operationComplete(ChannelFuture future) { 
    if (future.isSuccess()) { 
     // connection complete start to read first data 
     LOG.log(Level.INFO, "Connected to {0}:{1} successfully.", 
      new Object[]{connectionInfo.getHost(), connectionInfo.getPort().toString()}); 
    } else { 
     // Close the connection if the connection attempt has failed. 
     LOG.log(Level.WARNING, "Connection problem to {0}:{1}.", 
      new Object[]{connectionInfo.getHost(), connectionInfo.getPort().toString()}); 
    } 
    } 
}); 
// Wait until the connection is closed. 
f.channel().closeFuture().sync(); 

Zweite Lösung sieht einfacher und ich werde es vorziehen.

Verwandte Themen