2014-04-08 2 views
0

소켓 프로그래밍 및 Netty 프레임 워크를 처음 사용합니다. Echo Server example을 수정하여 메시지가 수신 되 자마자 클라이언트에서 메시지가 전송되지 않도록 시도했지만 다른 스레드의 호출이 클라이언트가 서버에 메시지를 보내도록 트리거합니다.netty 소켓 프로그래밍에서 외부 호출로 메시지 보내기

문제는 클라이언트가 매개 변수 (ChannelHandlerContext)로 서버를 지정한 readChannel 또는 MessageReceived 또는 channelActive에서 클라이언트가 메시지를 보내지 않으면 서버가 메시지를받지 못한다는 것입니다. 나는 서버 채널을 저장하고 나중에 그리고 반복적으로 메시지를 보내는 방법을 찾을 수 없었다.

다음은 내 클라이언트 처리기 코드입니다. 클라이언트 핸들러를 만들면

import io.netty.channel.ChannelHandlerAdapter; 
import io.netty.channel.ChannelHandlerContext; 

public class EchoClientHandler extends ChannelHandlerAdapter { 

    ChannelHandlerContext server; 

    @Override 
    public void channelActive(ChannelHandlerContext ctx) { 
     this.server = ctx; 
    } 

    @Override 
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 
     // ctx.write(msg); //not 
    } 

    @Override 
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 
     //ctx.flush(); 
    } 
    public void externalcall(String msg) throws Exception { 
     if(server!=null){ 
      server.writeAndFlush("[" + "] " + msg + '\n'); 
     } 
    } 
    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
     // Close the connection when an exception is raised. 
     ctx.close(); 
    } 
} 

는 또한 externalcall() 메소드를 호출하도록 파라미터로서 처리기를 가져 "SourceGenerator"개체 스레드를 생성한다.

import io.netty.bootstrap.Bootstrap; 
    import io.netty.channel.ChannelFuture; 
    import io.netty.channel.ChannelInitializer; 
    import io.netty.channel.ChannelOption; 
    import io.netty.channel.EventLoopGroup; 
    import io.netty.channel.nio.NioEventLoopGroup; 
    import io.netty.channel.socket.SocketChannel; 
    import io.netty.channel.socket.nio.NioSocketChannel; 

    /** 
    * Sends one message when a connection is open and echoes back any received 
    * data to the server. Simply put, the echo client initiates the ping-pong 
    * traffic between the echo client and server by sending the first message to 
    * the server. 
    */ 
    public class EchoClient { 

     private final String host; 
     private final int port; 

     public EchoClient(String host, int port, int firstMessageSize) { 
      this.host = host; 
      this.port = port; 
     } 
     public void run() throws Exception { 
      // Configure the client. 
      EventLoopGroup group = new NioEventLoopGroup(); 
      final EchoClientHandler x = new EchoClientHandler(); 
      SourceGenerator sg = new SourceGenerator(x); 
      new Thread(sg).start(); 
      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 { 
         ch.pipeline().addLast(x); 
        } 
       }); 

       // Start the client. 
       ChannelFuture f = b.connect(host, port).sync(); 

       // Wait until the connection is closed. 
       f.channel().closeFuture().sync(); 
      } finally { 
       // Shut down the event loop to terminate all threads. 
       group.shutdownGracefully(); 
      } 
     } 

     public static void main(String[] args) throws Exception { 
      // Print usage if no argument is specified. 
      if (args.length < 2 || args.length > 3) { 
       System.err.println(
         "Usage: " + EchoClient.class.getSimpleName() + 
         " <host> <port> [<first message size>]"); 
       return; 
      } 
      // Parse options. 
      final String host = args[0]; 
      final int port = Integer.parseInt(args[1]); 
      final int firstMessageSize; 
      if (args.length == 3) { 
       firstMessageSize = Integer.parseInt(args[2]); 
      } else { 
       firstMessageSize = 256; 
      } 

      new EchoClient(host, port, firstMessageSize).run(); 
     } 
    } 

및 SourceGenerator 클래스.

public class SourceGenerator implements Runnable { 
    public String dat; 
    public EchoClientHandler asd; 
    public SourceGenerator(EchoClientHandler x) { 
     asd = x; 
     System.out.println("initialized source generator"); 
     dat = ""; 
    } 

    @Override 
    public void run() { 
     try{ 
      while(true){ 
       Thread.sleep(2000); 
       dat += "a"; 
       asd.externalcall(dat); 
       System.out.print("ha!"); 
      } 
     }catch(Exception e){ 
      e.printStackTrace(); 

     } 
    } 
} 

미리 감사드립니다.

답변

1

문자열을 작성하려면 ChannelEncoder가 ChannelPipeline에 있어야합니다. 그렇지 않으면 ByteBuf 인스턴스 만 보낼 수 있습니다.

+0

효과가있었습니다. 다시 한 번 감사드립니다. –

관련 문제