Files
notes_estom/Java/JavaDemo/codedemo/reactor/Reader.java
2025-09-14 03:49:42 -04:00

95 lines
2.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package cn.aofeng.demo.reactor;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* 负责读取客户端的请求数据并解析。
*
* @author <a href="mailto:aofengblog@163.com">NieYong </a>
*/
public class Reader {
private final static Logger _logger = Logger.getLogger(Reader.class.getName());
private SocketChannel _clientChannel;
private Decoder _decoder;
private final static int BUFFER_SIZE = 512;
private ByteBuffer _buffer = ByteBuffer.allocate(BUFFER_SIZE);
public Reader(Selector selector, SocketChannel clientChannel) {
this._clientChannel = clientChannel;
}
public void setDecoder(Decoder decoder) {
this._decoder = decoder;
}
public void read() throws IOException {
int readCount = _clientChannel.read(_buffer);
if (-1 == readCount) {
_clientChannel.close();
}
_buffer.flip();
int oldLimit = _buffer.limit();
String line = null;
while( (line = (String) _decoder.decode(_buffer)) != null ) { // 处理一次多行发送过来的情况
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("收到的数据:"+line);
}
// 处理业务逻辑
ProcessService service= new ProcessService(_clientChannel, line);
String result = service.execute();
// 发送响应
Writer writer = new Writer(_clientChannel, result);
writer.setEncoder(new LineEncoder());
writer.write();
// 重建临时数据缓冲区
rebuildBuffer(line.length());
}
// 缓冲区数据还没有符合一个decode数据的条件重置数据缓冲区的状态方便append数据
if (oldLimit == _buffer.limit()) {
resetBuffer();
}
}
private void resetBuffer() {
_buffer.position(_buffer.limit());
_buffer.limit(_buffer.capacity());
}
/**
* 重建临时数据缓冲区。
*
* @param lineSize 收到的一行数据(不包括行结束符)的长度
*/
private void rebuildBuffer(int lineSize) {
if (_buffer.limit() == lineSize) {
// 数据刚好是一行
_buffer = ByteBuffer.allocate(BUFFER_SIZE);
} else if (_buffer.limit() > lineSize) {
// 数据多于一行
byte[] temp = new byte[_buffer.limit() - lineSize];
System.arraycopy(_buffer.array(), lineSize, temp, 0, temp.length);
_buffer = ByteBuffer.allocate(BUFFER_SIZE);
_buffer.put(temp);
_buffer.flip();
} else {
// nothing
}
}
}