/**
* Connects to endpoint, communicates with the server, and fires events to
* {@link IoHandler}s.
连接器IoConnector,可以连接终端与服务通信,触发IoHandler的相关事件。
*
* Please refer to
* [url=../../../../../xref-examples/org/apache/mina/examples/netcat/Main.html]NetCat[/url]
* example.
*
* You should connect to the desired socket address to start communication,
* and then events for incoming connections will be sent to the specified
* default {@link IoHandler}.
在开始通信之前,你应该连接一个Socket地址,建立连接的相关事件将会发送到IoHandler。
*
* Threads connect to endpoint start automatically when
* {@link #connect(SocketAddress)} is invoked, and stop when all
* connection attempts are finished.
*当连接远端地址时,线程自动连接远端socket地址,当连接尝试完成时,线程关闭
* @author [url=http://mina.apache.org]Apache MINA Project[/url]
*/
public interface IoConnector extends IoService {
/**
* @return the connect timeout in seconds. The default value is 1 minute.
* 获取连接超时时间(s),默认为1分钟
* @deprecated
*/
@Deprecated
int getConnectTimeout();
/**获取连接超时时间(ms),默认为1分钟
* @return the connect timeout in milliseconds. The default value is 1 minute.
*/
long getConnectTimeoutMillis();
/**
* Sets the connect timeout in seconds. The default value is 1 minute.
* 设置连接超时时间,单位s
* @deprecated
* @param connectTimeout The time out for the connection
*/
@Deprecated
void setConnectTimeout(int connectTimeout);
/**
* Sets the connect timeout in milliseconds. The default value is 1 minute.
* 设置连接超时时间,单位ms
* @param connectTimeoutInMillis The time out for the connection
*/
void setConnectTimeoutMillis(long connectTimeoutInMillis);
/**
* @return the default remote address to connect to when no argument
* is specified in {@link #connect()} method.
获取默认的远程socket地址
*/
SocketAddress getDefaultRemoteAddress();
/**
* Sets the default remote address to connect to when no argument is
* specified in {@link #connect()} method.
* 设置默认的远端socket地址
* @param defaultRemoteAddress The default remote address
*/
void setDefaultRemoteAddress(SocketAddress defaultRemoteAddress);
//设置获取本地默认socket地址
/**
* @return the default local address
*/
SocketAddress getDefaultLocalAddress();
/**
* Sets the default local address
*
* @param defaultLocalAddress The default local address
*/
void setDefaultLocalAddress(SocketAddress defaultLocalAddress);
/**
* Connects to the {@link #setDefaultRemoteAddress(SocketAddress) default
* remote address}.
* 连接到默认远端地址
* @return the {@link ConnectFuture} instance which is completed when the
* connection attempt initiated by this call succeeds or fails.
* @throws IllegalStateException
* if no default remoted address is set.
*/
ConnectFuture connect();
/**
* Connects to the {@link #setDefaultRemoteAddress(SocketAddress) default
* remote address} and invokes the ioSessionInitializer
when
* the IoSession is created but before {@link IoHandler#sessionCreated(IoSession)}
* is invoked. There is [i]no[/i] guarantee that the ioSessionInitializer
* will be invoked before this method returns.
* 在连接默认远端地址,当会话创建时,在IoHandler#sessionCreated调用前,调用ioSessionInitializer
,初始化会话
* @param sessionInitializer the callback to invoke when the {@link IoSession} object is created
* @return the {@link ConnectFuture} instance which is completed when the
* connection attempt initiated by this call succeeds or fails.
*
* @throws IllegalStateException if no default remote address is set.
*/
ConnectFuture connect(IoSessionInitializer extends ConnectFuture> sessionInitializer);
/**
* Connects to the specified remote address.
* 连接到远端socket地址
* @param remoteAddress The remote address to connect to
* @return the {@link ConnectFuture} instance which is completed when the
* connection attempt initiated by this call succeeds or fails.
*/
ConnectFuture connect(SocketAddress remoteAddress);
/**
* Connects to the specified remote address and invokes
* the ioSessionInitializer
when the IoSession is created but before
* {@link IoHandler#sessionCreated(IoSession)} is invoked. There is [i]no[/i]
* guarantee that the ioSessionInitializer
will be invoked before
* this method returns.
* 连接远端地址,在会话创建时,在IoHandler#sessionCreated调用前,调用ioSessionInitializer
,初始化会话。
* @param remoteAddress the remote address to connect to
* @param sessionInitializer the callback to invoke when the {@link IoSession} object is created
*
* @return the {@link ConnectFuture} instance which is completed when the
* connection attempt initiated by this call succeeds or fails.
*/
ConnectFuture connect(SocketAddress remoteAddress, IoSessionInitializer extends ConnectFuture> sessionInitializer);
/**
* Connects to the specified remote address binding to the specified local address.
*连接远端地址,绑定本地地址
* @param remoteAddress The remote address to connect
* @param localAddress The local address to bind
*
* @return the {@link ConnectFuture} instance which is completed when the
* connection attempt initiated by this call succeeds or fails.
*/
ConnectFuture connect(SocketAddress remoteAddress, SocketAddress localAddress);
/**
* Connects to the specified remote address binding to the specified local
* address and and invokes the ioSessionInitializer
when the
* IoSession is created but before {@link IoHandler#sessionCreated(IoSession)}
* is invoked. There is [i]no[/i] guarantee that the ioSessionInitializer
* will be invoked before this method returns.
* 连接远端地址,绑定本地地址,在IoHandler#sessionCreated调用前,调用ioSessionInitializer
,初始化会话。
* @param remoteAddress the remote address to connect to
* @param localAddress the local interface to bind to
* @param sessionInitializer the callback to invoke when the {@link IoSession} object is created
*
* @return the {@link ConnectFuture} instance which is completed when the
* connection attempt initiated by this call succeeds or fails.
*/
ConnectFuture connect(SocketAddress remoteAddress, SocketAddress localAddress,
IoSessionInitializer extends ConnectFuture> sessionInitializer);
}
/**
* A base implementation of {@link IoConnector}.
*
* @author [url=http://mina.apache.org]Apache MINA Project[/url]
*/
public abstract class AbstractIoConnector extends AbstractIoService implements IoConnector {
/**
* The minimum timeout value that is supported (in milliseconds).
*/
private long connectTimeoutCheckInterval = 50L;//连接超时检查间隔
private long connectTimeoutInMillis = 60 * 1000L; // 1 minute by default,默认连接超时时间
/** The remote address we are connected to 连接的远端地址*/
private SocketAddress defaultRemoteAddress;
/** The local address 本地socket地址*/
private SocketAddress defaultLocalAddress;
}
/**
* Constructor for {@link AbstractIoConnector}. You need to provide a
* default session configuration and an {@link Executor} for handling I/O
* events. If null {@link Executor} is provided, a default one will be
* created using {@link Executors#newCachedThreadPool()}.
* 构造AbstractIoConnector,需要提供一个会话配置,一个执行器用于处理IO相关事件,
如果执行器为空,默认为Executors#newCachedThreadPool
* @see AbstractIoService#AbstractIoService(IoSessionConfig, Executor)
*
* @param sessionConfig
* the default configuration for the managed {@link IoSession}
* @param executor
* the {@link Executor} used for handling execution of I/O
* events. Can be null
.
*/
protected AbstractIoConnector(IoSessionConfig sessionConfig, Executor executor) {
super(sessionConfig, executor);
}
/**
* {@inheritDoc}
*/
@Override
public final ConnectFuture connect() {
SocketAddress remoteAddress = getDefaultRemoteAddress();
if (remoteAddress == null) {
throw new IllegalStateException("defaultRemoteAddress is not set.");
}
return connect(remoteAddress, null, null);
}
/**
* {@inheritDoc}
*/
@Override
public ConnectFuture connect(IoSessionInitializer extends ConnectFuture> sessionInitializer) {
SocketAddress remoteAddress = getDefaultRemoteAddress();
if (remoteAddress == null) {
throw new IllegalStateException("defaultRemoteAddress is not set.");
}
return connect(remoteAddress, null, sessionInitializer);
}
/**
* {@inheritDoc}
*/
@Override
public final ConnectFuture connect(SocketAddress remoteAddress) {
return connect(remoteAddress, null, null);
}
/**
* {@inheritDoc}
*/
@Override
public ConnectFuture connect(SocketAddress remoteAddress,
IoSessionInitializer extends ConnectFuture> sessionInitializer) {
return connect(remoteAddress, null, sessionInitializer);
}
/**
* {@inheritDoc}
*/
@Override
public ConnectFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) {
return connect(remoteAddress, localAddress, null);
}
/**
* {@inheritDoc}
*/
@Override
public final ConnectFuture connect(SocketAddress remoteAddress, SocketAddress localAddress,
IoSessionInitializer extends ConnectFuture> sessionInitializer) {
//检查连接器状态,检查本地地址与远程地址是否为空已经与传输元数据地址类型是否匹配
if (isDisposing()) {
throw new IllegalStateException("The connector is being disposed.");
}
if (remoteAddress == null) {
throw new IllegalArgumentException("remoteAddress");
}
if (!getTransportMetadata().getAddressType().isAssignableFrom(remoteAddress.getClass())) {
throw new IllegalArgumentException("remoteAddress type: " + remoteAddress.getClass() + " (expected: "
+ getTransportMetadata().getAddressType() + ")");
}
if (localAddress != null && !getTransportMetadata().getAddressType().isAssignableFrom(localAddress.getClass())) {
throw new IllegalArgumentException("localAddress type: " + localAddress.getClass() + " (expected: "
+ getTransportMetadata().getAddressType() + ")");
}
//如果连接器Iohandler为null,创建一个对会话操作事件不处理的IoHandler
if (getHandler() == null) {
if (getSessionConfig().isUseReadOperation()) {
setHandler(new IoHandler() {
/**
* {@inheritDoc}
*/
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
// Empty handler
}
/**
* {@inheritDoc}
*/
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
// Empty handler
}
/**
* {@inheritDoc}
*/
@Override
public void messageSent(IoSession session, Object message) throws Exception {
// Empty handler
}
/**
* {@inheritDoc}
*/
@Override
public void sessionClosed(IoSession session) throws Exception {
// Empty handler
}
/**
* {@inheritDoc}
*/
@Override
public void sessionCreated(IoSession session) throws Exception {
// Empty handler
}
/**
* {@inheritDoc}
*/
@Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
// Empty handler
}
/**
* {@inheritDoc}
*/
@Override
public void sessionOpened(IoSession session) throws Exception {
// Empty handler
}
/**
* {@inheritDoc}
*/
@Override
public void inputClosed(IoSession session) throws Exception {
// Empty handler
}
});
} else {
throw new IllegalStateException("handler is not set.");
}
}
return connect0(remoteAddress, localAddress, sessionInitializer);
}
/**
* Implement this method to perform the actual connect operation.
*实现具体的connect0
* @param remoteAddress The remote address to connect from
* @param localAddress null if no local address is specified
* @param sessionInitializer The IoSessionInitializer to use when the connection s successful
* @return The ConnectFuture associated with this asynchronous operation
*
*/
protected abstract ConnectFuture connect0(SocketAddress remoteAddress, SocketAddress localAddress,
IoSessionInitializer extends ConnectFuture> sessionInitializer);
/**
* Adds required internal attributes and {@link IoFutureListener}s
* related with event notifications to the specified {@code session}
* and {@code future}. Do not call this method directly;
添加必要的内部属性和结果监听器到会话和future,不要直接调用此方法。
*/
@Override
protected final void finishSessionInitialization0(final IoSession session, IoFuture future) {
// In case that ConnectFuture.cancel() is invoked before
// setSession() is invoked, add a listener that closes the
// connection immediately on cancellation.
//防止在设置会话时,连接请求被取消,添加一个监听器,当连接取消时,
//关闭会话。
future.addListener(new IoFutureListener() {
/**
* {@inheritDoc}
*/
@Override
public void operationComplete(ConnectFuture future) {
if (future.isCanceled()) {
session.closeNow();
}
}
});
}
/**
* @return
* The minimum time that this connector can have for a connection
* timeout in milliseconds.
*/
public long getConnectTimeoutCheckInterval() {
return connectTimeoutCheckInterval;
}
/**
* Sets the timeout for the connection check
*
* @param minimumConnectTimeout The delay we wait before checking the connection
*/
public void setConnectTimeoutCheckInterval(long minimumConnectTimeout) {
if (getConnectTimeoutMillis() < minimumConnectTimeout) {
this.connectTimeoutInMillis = minimumConnectTimeout;
}
this.connectTimeoutCheckInterval = minimumConnectTimeout;
}
/**
* @deprecated Take a look at getConnectTimeoutMillis()
*/
@Deprecated
@Override
public final int getConnectTimeout() {
return (int) connectTimeoutInMillis / 1000;
}
/**
* {@inheritDoc}
*/
@Override
public final long getConnectTimeoutMillis() {
return connectTimeoutInMillis;
}
/**
* @deprecated
* Take a look at setConnectTimeoutMillis(long)
*/
@Deprecated
@Override
public final void setConnectTimeout(int connectTimeout) {
setConnectTimeoutMillis(connectTimeout * 1000L);
}
/**
* Sets the connect timeout value in milliseconds.
*
*/
@Override
public final void setConnectTimeoutMillis(long connectTimeoutInMillis) {
if (connectTimeoutInMillis <= connectTimeoutCheckInterval) {
this.connectTimeoutCheckInterval = connectTimeoutInMillis;
}
this.connectTimeoutInMillis = connectTimeoutInMillis;
}
/**
* {@inheritDoc}
*/
@Override
public SocketAddress getDefaultRemoteAddress() {
return defaultRemoteAddress;
}
/**
* {@inheritDoc}
*/
@Override
public final void setDefaultLocalAddress(SocketAddress localAddress) {
defaultLocalAddress = localAddress;
}
/**
* {@inheritDoc}
*/
@Override
public final SocketAddress getDefaultLocalAddress() {
return defaultLocalAddress;
}
/**
* {@inheritDoc}
*/
@Override
public final void setDefaultRemoteAddress(SocketAddress defaultRemoteAddress) {
if (defaultRemoteAddress == null) {
throw new IllegalArgumentException("defaultRemoteAddress");
}
if (!getTransportMetadata().getAddressType().isAssignableFrom(defaultRemoteAddress.getClass())) {
throw new IllegalArgumentException("defaultRemoteAddress type: " + defaultRemoteAddress.getClass()
+ " (expected: " + getTransportMetadata().getAddressType() + ")");
}
this.defaultRemoteAddress = defaultRemoteAddress;
}
public interface IoSessionInitializer
{
public abstract void initializeSession(IoSession iosession, IoFuture iofuture);
}