2011-01-26 4 views
3

작은 자바 서버 유형 앱에 여러 연결을 허용하려고합니다. 있는 그대로 작동하지만 하나의 연결이 열렸다가 멈 추면 모든 후속 연결이 중단됩니다. 나는 스레드가 속한 추적을 유지하면서 자신의 스레드에서 약 20 동시 것들까지, 각 연결 처리에 대한 이동하는 방법을 잘 모르겠어요에 내가 지금까지 가지고있는 코드는 등 어떤 클라이언트 :이 비 차단 서버를 멀티 스레드로 만들려면 어떻게해야합니까?

private void init() { 
    try { 
     // Create the server socket channel 
     ServerSocketChannel server = ServerSocketChannel.open(); 
     // nonblocking I/O 
     server.configureBlocking(false); 
     // host-port 
     server.socket().bind(new InetSocketAddress(host, port)); 
     System.out.println("Server connected on " + host + ":" + port); 
     // Create the selector 
     Selector selector = Selector.open(); 
     // Recording server to selector (type OP_ACCEPT) 
     server.register(selector, SelectionKey.OP_ACCEPT); 
     // Infinite server loop 
     for (;;) { 
      // Waiting for events 
      selector.select(); 
      // Get keys 
      Set keys = selector.selectedKeys(); 
      Iterator i = keys.iterator(); 
      // For each keys... 
      while (i.hasNext()) { 
       SelectionKey key = (SelectionKey) i.next(); 
       // Remove the current key 
       i.remove(); 
       // if isAccetable = true 
       // then a client required a connection 
       if (key.isAcceptable()) { 
        // get client socket channel 
        SocketChannel client = server.accept(); 
        // Non Blocking I/O 
        client.configureBlocking(false); 
        // recording to the selector (reading) 
        client.register(selector, SelectionKey.OP_READ); 
        continue; 
       } 
       // then the server is ready to read 
       if (key.isReadable()) { 
        SocketChannel client = (SocketChannel) key.channel(); 
        // Read byte coming from the client 
        int BUFFER_SIZE = 32; 
        ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); 
        try { 
         client.read(buffer); 
        } catch (Exception e) { 
         // client is no longer active 
         e.printStackTrace(); 
         continue; 
        } 
        buffer.flip(); 
        Charset charset = Charset.forName("ISO-8859-1"); 
        CharsetDecoder decoder = charset.newDecoder(); 
        CharBuffer charBuffer = decoder.decode(buffer); 
        Handler dataHandler = new Handler(); 
        client.write(ByteBuffer.wrap(dataHandler.processInput(charBuffer.toString()).getBytes())); 
        client.socket().close(); 
        continue; 
       } 
      } 
     } 
    } catch (IOException ex) { 
     Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 
+0

에서

봐 난 그냥 NIO을 차단 사용 및 클라이언트 당 하나 개의 스레드를 가질 것, 그것은 훨씬 더 간단하고 10K 연결까지 확장 할 수 있습니다. 또한 더 효율적일 수 있습니다. –

답변

1

내 솔루션은 ThreadPool을 생성하는 Netty 및 Executor입니다. 실행기 마녀 ChannelBuffer를 매개 변수로 호출하는 처리기 do Netty의 파이프 라인을 추가하기 만하면됩니다. 모든 클라이언트 요청이 별도의 스레드에 의해 처리됩니다. examples

+0

감사합니다.) – zcourts

+0

끝 부분에 네티 (netty)가 있고, 외부 deps는 없습니다. API에 익숙해지기 위해서는 학습 곡선이 얼마나 가파른가요? – zcourts

+0

분당 기본 서버를 만들 수 있지만 작동 방식을 알기 위해서는 netty 소스에 깊이 들어가면 좋습니다. 그것은 나를위한 좋은 교훈이다 : 나는 핸들러 - 디코더/인코더에서 빌드에 대해 읽는 것을 권장한다. 파이프 라인에 몇 개의 클래스를 추가하기 만하면 서버를 구축 할 수 있습니다. HTTP, SSL, 원하는 것은 무엇이든 :) –

3

소켓 서버를 작성해야 할 때마다 하위 수준의 JVM 클래스는 사용하지 않는 것이 좋습니다. 그 이유는 모든 핵심적인 세부 사항을 처리해야하기 때문입니다.

대신 Apache Mina을 사용합니다. 고성능 논 블로킹 멀티 쓰레드 소켓 서버를 작성하기위한 자바 라이브러리.

미나 (Mina)를 사용할 때의 이점은 코드를 모듈화하고 관리하기 쉽게 만드는 clean architecture (IoFilters, 프로토콜 디코더)을 시행한다는 것입니다.

+0

매우 유망한 소리 ... 나는 한번 살펴보고 돌아올 것이다. 아파치 프로젝트에 더 익숙해 져야합니다 ... – zcourts

2

NIO 서버를 학습 연습으로 쓰고 싶지 않다면 Netty을 사용하는 것이 좋습니다. Peter가 언급 한 Mina와 마찬가지로 고성능 서버를 작성하기위한 라이브러리이기도합니다.

최근에 내 자신의 NIO 코드를이 라이브러리로 옮겨서 코드를 훨씬 더 명확하게 만들었습니다.

+0

나는 체크 아웃 네트를 사용하기 때문에 너무 많은 오버 헤드없이 간단하게 생활 할 수있는 모든 것입니다. – zcourts

관련 문제