2014-10-31 172 views
2

我想做一個簡單的聊天。 服務器必須在客戶端列表中添加新客戶端,並且當一個客戶端向服務器發送消息時,服務器必須將此消息重新發送給其他客戶端。 我知道,如何從客戶端讀取消息,但我不知道如何從服務器向客戶端發送消息。我不確定客戶端應該在哪裏,但是在處理程序類中猜測。 這裏是一個初始化服務器類Netty服務器如何將數據發送到不同的客戶端?

package firstPackage; 

public class main { 

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

這裏我的主類是服務器類

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(); 
    } 
} 

} 

而且這裏的Handler類

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(); 
} 
} 

其實我現在還沒有客戶名單,因爲我甚至不知道這個列表必須包含什麼類型的對象,在C#中它是Socket對象,那麼在Netty中呢?

回答

1

我敢打賭,this example應該會幫助你(這是一個YouTube視頻,所以請留下有關斷開鏈接的評論)。特別是,它使用ChannelGroup來解決你所問的問題。而且,是的,它在服務器端的處理程序中。

編輯:

注意過,在示例中ChannelGroup是靜態的。我可能會爭辯說最好不要使用靜態成員,並從服務器類中將ChannelGroup注入到處理程序中,但如果您只想快速獲得某些內容,則靜態成員的簡單性可能更好。

相關問題