package io.mycat.net;
import java.io.IOException;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author wuzh
*/
public abstract class ConnectionFactory {
/**
* 创建一个具体的连接
*
* @param channel
* @return Connection
* @throws IOException
*/
protected abstract Connection makeConnection(SocketChannel channel)
throws IOException;
/**
* NIOHandler是无状态的,多个连接共享一个,因此建议作为 Factory的私有变量
*
* @return NIOHandler
*/
@SuppressWarnings("rawtypes")
protected abstract NIOHandler getNIOHandler();
@SuppressWarnings("unchecked")
public Connection make(SocketChannel channel) throws IOException {
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
// 子类完成具体连接创建工作
Connection c = makeConnection(channel);
// 设置连接的参数
NetSystem.getInstance().setSocketParams(c,true);
// 设置NIOHandler
c.setHandler(getNIOHandler());
return c;
}
}
@SuppressWarnings("rawtypes")
class NIOHandlerWrap implements NIOHandler {
protected static final Logger LOGGER = LoggerFactory
.getLogger(NIOHandlerWrap.class);
private final NIOHandler handler;
public NIOHandlerWrap(NIOHandler handler) {
super();
this.handler = handler;
}
@SuppressWarnings("unchecked")
@Override
public void onConnected(Connection con) throws IOException {
con.setState(Connection.State.connecting);
String info = con.getDirection() == Connection.Direction.in ? "remote peer connected to me "
+ con
: " connected to remote peer " + con;
LOGGER.info(info);
handler.onConnected(con);
}
@SuppressWarnings("unchecked")
@Override
public void onConnectFailed(Connection con, Throwable e) {
LOGGER.warn("connection failed: " + e + " con " + con);
handler.onConnectFailed(con, e);
}
@SuppressWarnings("unchecked")
@Override
public void handle(Connection con, ByteBuffer data, int start,
int readeLength) {
handler.handle(con, data, start, readeLength);
}
@SuppressWarnings("unchecked")
@Override
public void onClosed(Connection con, String reason) {
handler.onClosed(con, reason);
}
}