2014-10-31 2 views
2

나는 간단한 채팅과 같은 것을 만들고 싶다. 서버는 클라이언트 목록에 새 클라이언트를 추가해야하며 한 클라이언트가 서버에 메시지를 보내면 서버는이 메시지를 다른 클라이언트에 다시 보내야합니다. 클라이언트에서 메시지를 읽는 방법을 알고 있지만 서버에서 클라이언트로 메시지를 보내는 방법을 알고 있습니다. 그리고 나는 클라이언트의리스트가 어디 있는지 확실하지 않지만, 핸들러 클래스에서는 그렇게 생각한다. 여기에 지금은 클라이언트의 목록을하지 않은 서버 클래스Netty 서버가 어떻게 다른 클라이언트에 데이터를 보낼 수 있습니까?

package firstPackage; 

import io.netty.bootstrap.ServerBootstrap; 
import io.netty.channel.*; 
import io.netty.channel.nio.NioEventLoopGroup; 
import io.netty.channel.socket.nio.NioServerSocketChannel; 

import io.netty.channel.socket.SocketChannel; 


public class Server { 

private int port; 

public Server(int port) 
{ 
    this.port=port; 
} 

public void run() throws Exception 
{ 
    EventLoopGroup bossGroup = new NioEventLoopGroup(); 
    EventLoopGroup workerGroup = new NioEventLoopGroup(); 

    try{ 
     ServerBootstrap b = new ServerBootstrap(); 
     b.group(bossGroup,workerGroup) 
     .channel(NioServerSocketChannel.class) 
     .childHandler(new ChannelInitializer<SocketChannel>() { 
      @Override 
      public void initChannel(SocketChannel ch) throws Exception{ 
       ch.pipeline().addLast(new DiscardServerHandler()); 
      } 
     }) 
     .option(ChannelOption.SO_BACKLOG,128) 
     .childOption(ChannelOption.SO_KEEPALIVE, true); 

     ChannelFuture f = b.bind(port).sync(); 
     f.channel().closeFuture().sync(); 
    } 
    finally { 
     workerGroup.shutdownGracefully(); 
     bossGroup.shutdownGracefully(); 
    } 
} 

} 

그리고 여기

package firstPackage; 

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

public class DiscardServerHandler extends ChannelInboundHandlerAdapter { 

@Override 
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 
    ByteBuf in = (ByteBuf) msg; 
    try { 
     while (in.isReadable()) { 
      System.out.print((char) in.readByte()); 
      System.out.flush(); 
     } 
     System.out.println(); 

     ctx.writeAndFlush("hey"); // вот здесь я думал, что сообщение будет отправлятся клиенту, от которого я получил сообщение, но не отправляется 

    } finally { 
     ReferenceCountUtil.release(msg); 
    } 
} 

@Override 
public void channelActive(ChannelHandlerContext ctx) throws Exception { 
    System.out.println("channel is active"); 
} 

@Override 
public void channelInactive(ChannelHandlerContext ctx) throws Exception { 
    System.out.println("channel is invactive"); 
} 

@Override 
public void handlerAdded(ChannelHandlerContext ctx) throws Exception { 
    System.out.println("handler added"); 
} 

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

실제로 핸들러 클래스 다음은 서버 클래스를

package firstPackage; 

public class main { 

    public static void main(String[] args) throws Exception 
    { 
    Server server = new Server(9050); 
    server.run(); 
    } 
} 

를 초기화 내 주요 클래스입니다 왜냐하면 나는이 목록에 포함되어야하는 객체의 유형을 알지 못하기 때문에 C#에서는 소켓 객체 였기 때문에 Netty에서 무엇을 할 수 있습니까?

답변

1

저는 this example이 당신을 도울 것입니다 (YouTube 동영상이므로 깨진 링크에 대한 의견을 남겨주세요). 특히 ChannelGroup을 사용하여 요청한 문제를 해결합니다. 그리고 네, 그것은 서버 측의 핸들러에 들어갑니다.

편집 :

주의도 그 예에서 ChannelGroup 정적이다. 정적 멤버를 사용하지 않고 서버 클래스의 핸들러에 ChannelGroup을 삽입하는 것이 더 나을 것이라고 주장 할 수도 있지만, 빠르게 작동하는 것을 얻으려면 정적 멤버의 단순성이 바람직 할 수 있습니다.

관련 문제