服务器和客户端共同继承适配器类IoHandlerAdapter
* 当客户端发来消息之后,会先调用自定义的解码器(类)。
* 当解码器解码完成之后,再来这里进行业务处理。
* 处理完之后(也就是调用write()方法之后),会再调用自定义的编码器(类)
* 编码器(类)处理完之后,就发给客户端了。
1. 服务器端的实现 FileObjectServerHandler
/**
* 当客户端发来消息之后,会先调用自定义的解码器(类)。
* 当解码器解码完成之后,再来这里进行业务处理。
* 处理完之后(也就是调用write()方法之后),会再调用自定义的编码器(类)
* 编码器(类)处理完之后,就发给客户端了。
* @author king_fu
*
*/
public class FileObjectServerHandler extends IoHandlerAdapter {
private static final Logger LOGGER = LoggerFactory
.getLogger(FileObjectServerHandler.class);
@Override
public void sessionCreated(IoSession session) throws Exception {
LOGGER.info("客戶端又來了");
}
@Override
public void sessionOpened(IoSession session) throws Exception {
LOGGER.info("客戶端:" + session.getRemoteAddress().toString());
}
@Override
public void sessionClosed(IoSession session) throws Exception {
LOGGER.info("客戶端失去連接");
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
LOGGER.info("服務器空閒中");
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
LOGGER.info("服務器與客戶端交互發生異常");
super.exceptionCaught(session, cause);
}
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
ByteFileMessage fm = (ByteFileMessage) message;
PropertiesModel pm = ReadProperties.getModel();
OutputStream os = null;
try {
// 用ObjectOutputStream的方式进行保存,打开之后会有乱码现象
/*os = new ObjectOutputStream(new FileOutputStream(
pm.getServerFilePath() + System.currentTimeMillis()
+ fm.getFileName()));
os.write(fm.getFileStream());
os.flush();*/
// 用PrintStream
os = new PrintStream(new FileOutputStream(
pm.getServerFilePath() + System.currentTimeMillis()
+ fm.getFileName()));
os.write(fm.getFileStream());
os.flush();
} finally {
os.close();
}
ByteReturnFileMessage brf = new ByteReturnFileMessage();
brf.setSeq(fm.getSeq());
brf.setReturnMassage("服务器保存文件完成。");
brf.setReturnMassageLength(brf.getReturnMassage().getBytes().length);
session.write(brf);
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
LOGGER.info("服務器信息已送達");
}
}
* 客户端如果添加了自定义编码解码类
* 那么,在发送给服务器的时候,信息会先经过编码器(类)
* 然后再发送给服务器;
*
* 如果实现了解码器,那么在服务器发送信息过来之后,
* 就会先调用解码器。然后再进行业务处理
/**
* 客户端如果添加了自定义编码解码类
* 那么,在发送给服务器的时候,信息会先经过编码器(类)
* 然后再发送给服务器;
*
* 如果实现了解码器,那么在服务器发送信息过来之后,
* 就会先调用解码器。然后再进行业务处理
* @author king_fu
*
*/
public class FileObjectClientHandler extends IoHandlerAdapter {
private static final Logger LOGGER = LoggerFactory
.getLogger(FileObjectClientHandler.class);
@Override
public void sessionOpened(IoSession session) throws Exception {
ByteFileMessage bfm = new ByteFileMessage();
PropertiesModel pm = ReadProperties.getModel();
if (!(new File(pm.getClientFilePath()).isDirectory())) {
// 如果不是目录
LOGGER.debug("当前目录:" + pm.getClientFilePath());
throw new MyRuntimeException("在配置文件中未指定正确的目录路径:clientFilePath");
}
if (!(new File(pm.getClientFilePath() + pm.getClientFileName())
.isFile())) {
// 如果不是文件
LOGGER.debug("当前文件:" + pm.getClientFilePath()
+ pm.getClientFileName());
throw new MyRuntimeException("在配置文件中未指定正确的文件路径:clientFileName");
}
bfm.setSeq(1);
// 封装文件路径;路径名+文件名
bfm.setFilePath(pm.getClientFilePath() + pm.getClientFileName());
session.write(bfm);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
LOGGER.info("客户端與服务器交互發生異常");
super.exceptionCaught(session, cause);
}
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
ByteReturnFileMessage returnMessage = (ByteReturnFileMessage) message;
LOGGER.info("返回的序号:" + returnMessage.getSeq());
LOGGER.info("服务器返回的消息:" + returnMessage.getReturnMassage());
session.close(true);
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
LOGGER.info("客户端信息已送達");
}
}
到了这里,客户端和服务器的IoHandle实现了。
最新代码已经更新在github中,欢迎fork。
项目名:MinaFile