0

我想创建一个聊天服务器来处理不同房间的 100-500 个用户。
我决定使用 Netty 框架,因为基于事件的架构(这对我来说非常熟悉)。我从小型服务器开始,它对收到的所有内容都响应“NYA”。主要的:

    public class ChatServer{
    public static void main(String[] args) throws Exception {
        ExecutorService bossExec = new OrderedMemoryAwareThreadPoolExecutor(1, 400000000, 2000000000, 60, TimeUnit.SECONDS);
        ExecutorService ioExec = new OrderedMemoryAwareThreadPoolExecutor(4 /* число рабочих потоков */, 400000000, 2000000000, 60, TimeUnit.SECONDS);

        ChannelFactory factory = new NioServerSocketChannelFactory(bossExec,ioExec);
        ServerBootstrap bootstrap = new ServerBootstrap(factory);

        bootstrap.setPipelineFactory(new ChannelPipelineFactory(){
            public ChannelPipeline getPipeline(){
                return Channels.pipeline(new ChatChannelHandler());
            }
        });

        bootstrap.setOption("child.tcpNoDelay", true);
        bootstrap.setOption("child.keepAlive", true);
        bootstrap.setOption("reuseAddress", true);

        bootstrap.bind(new InetSocketAddress(5555));

        System.out.println("ChatServer started at last...");
    }
}

处理程序:

public class ChatChannelHandler extends SimpleChannelUpstreamHandler {

    private final ChannelBuffer messageBuffer = ChannelBuffers.dynamicBuffer();
    private boolean processingMessage = false;
    private short messageLength;

    @Override
    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        System.out.println("Connection from: " + e.getChannel().getRemoteAddress().toString());
    }

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
        e.getChannel().write(ChannelBuffers.copiedBuffer("NYA!", "UTF-8");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
        System.out.println("Exception: " + e.getCause());
        Channel ch = e.getChannel();
        ch.close();
    }
}

我使用模拟程序创建 N 个连接,然后随机将内容写入服务器,暂停 1-5 秒。然后我连接我的基于 Flash 的客户端,看看它是如何工作的。所以问题是,在 10-90 个连接下,我的 flash 客户端立即从服务器获得响应,但是当模拟连接数超过 100 时,我的 flash 客户端保持沉默。我只是不明白为什么。
我发现,来自我的 100 多个客户端的所有消息都进入缓冲区,但 messageReceive 事件根本没有为它们触发。看起来事件队列达到了注册事件的某些限制,或者类似的东西。
我真的很难过,因为我读到更简单的服务器每秒处理 1k+ 请求。
如果有必要,我在 Windows 7 下工作。此外,我的服务器从不使用超过 2-3% 的 CPU。

我的模拟生成器:

public class ClientLoadEmulation implements Runnable {

    private String host;
    private int port;
    private static final int minStringLength = 5;
    private static final int maxStringLength = 40;
    private static final int minPause = (int) (1 * 1000);
    private static final int maxPause = (int) (5 * 1000);
    Random rand = new Random();

    public ClientLoadEmulation(String host, int port, int numThreads) {
        this.host = "192.168.0.100";
        this.port = 5555;
        for (int i = 0; i < numThreads; ++i) {
            new Thread(this).start();
            try {
                Thread.sleep(100);
            } catch (Exception ex) {
            }
        }
    }

    @Override
    public void run() {

        byte buffer[] = new byte[255];

        try {
            Socket s = new Socket(host, port);
            InputStream in = s.getInputStream();
            OutputStream out = s.getOutputStream();
            while (true) {
                String govno = "";
                ...STRING GENERATION STUFF CUTTED...
                ByteBuffer LENGTH_BUFFER = ByteBuffer.allocate(2);
                LENGTH_BUFFER.putShort((short) govno.length());
                LENGTH_BUFFER.flip();
                out.write(LENGTH_BUFFER.array());
                out.write(govno.getBytes("UTF-8"));
                //System.out.println(Thread.currentThread() + " wrote " + govno);

                int pause = minPause
                        + (int) (rand.nextDouble() * (maxPause - minPause));
                try {
                    Thread.sleep(pause);
                } catch (InterruptedException ie) {
                }
                }
        } catch (IOException ie) {
            System.out.println("ERROR: " + ie.getMessage());
        }
    }

    static public void main(String args[]) throws Exception {
        new ClientLoadEmulation("127.0.0.1", 5555, 100);
    }
}

(对不起我的英语水平)

4

1 回答 1

0

我不确定您的示例,但是当我尝试运行您提供的 ChatServer 时,它不是在等待客户端连接,而是退出。

此外,我根本看不到端口 5555 设置(客户端期望的那个)。

请发布工作样本以进行检查。

于 2012-08-21T19:28:46.843 回答