Java/Java 구현

Java // 구현 // Client SocketChannel (in Server) // NIO NonBlocking

문스코딩 2018. 8. 3. 13:11


- NIO NonBlocking 기반 서버의 클라이언트 추상클래스

- NonBlocking이라서 receive() 메소드에 스레드를 할당하지 않아도 Selector가 메소드를 실행

- "route()"와 "terminate()"를  메소드 오버라이딩해서 처리


public abstract class Client {

/* Field */
public SocketChannel socketChannel;
public SelectionKey selectionKey;
public Selector selector;
public String response;
private Charset charset = Charset.forName("UTF-8");

/* Constructor */
public Client(SocketChannel socketChannel, Selector selector) {
try {
this.socketChannel = socketChannel;
this.selector = selector;
this.response = "";

// == OP_READ - SelectionKey 추가 ==
this.socketChannel.configureBlocking(false);
this.selectionKey = this.socketChannel.register(this.selector, SelectionKey.OP_READ);
this.selectionKey.attach(this);

} catch (IOException e) {
e.printStackTrace();
}
}

/* Receive */
public void receive() {
try {
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

// == Request ==
int byteCount = socketChannel.read(byteBuffer);
if (byteCount == -1) throw new IOException(); // == close() 호출 (정상종료) ==
byteBuffer.flip();
String reqeust = charset.decode(byteBuffer).toString();

// == route ==
route(reqeust);

} catch (IOException errB) {
terminate();
}
}

/* Route */
protected abstract void route(String request);

/* Send */
public void send() {
try {
// == write ==
selectionKey.interestOps(SelectionKey.OP_WRITE);
ByteBuffer byteBuffer = charset.encode(this.response);
socketChannel.write(byteBuffer);

// == wakeup ==
selectionKey.interestOps(SelectionKey.OP_READ);
this.selector.wakeup();

} catch (IOException e) {
terminate();
}
}

/* Terminate */
protected abstract void terminate();

}


반응형