org.appconn.channel.TcpClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of appconn Show documentation
Show all versions of appconn Show documentation
Java library for easy and fast implementation of distributed applications, including, optimized
serialization, high availability administration and server resources management.
package org.appconn.channel;
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* appconn AbstractClient TCP implementation.
*/
final class TcpClient extends AbstractClient {
private final SocketChannel channel;
private final Selector selector;
/**
* Constructs a new TcpClient.
* @param remote the remote SocketAddress
* @param connectTimeout the connectTimeout in millis
* @param keepAlive the keepAlive
* @param readBufferLength the readBufferLength
* @param writeBufferLength the writeBufferLength
* @param returns the Returns implementation instance
* @throws IOException if an I/O exception of some sort has occurred
*/
TcpClient(SocketAddress remote, int connectTimeout, boolean keepAlive, int readBufferLength, int writeBufferLength, Returns returns) throws IOException {
super(TcpClient.class.getName());
channel = SocketChannel.open();
channel.socket().connect(remote, connectTimeout);
channel.socket().setKeepAlive(keepAlive);
channel.socket().setTcpNoDelay(true);
channel.configureBlocking(false);
readBuffer = new ReadHeapByteBuffer(channel, readBufferLength);
writeBuffer = new WriteHeapByteBuffer(channel, writeBufferLength);
selector = Selector.open();
channel.register(selector, SelectionKey.OP_READ, new ClientHandler(channel));
this.returns = returns;
start();
Logger.getLogger("org.appconn").log(Level.FINE, "connected to " + channel.getRemoteAddress());
}
@Override
public void run() {
while (true) {
try {
selector.select();
Iterator iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
((Handler) selectionKey.attachment()).handle();
}
} catch (IOException e) {
Logger.getLogger("org.appconn").log(Level.WARNING, e, e::getMessage);
break;
} catch (ClosedSelectorException e) {
break;
}
}
}
@Override
public void interrupt() {
try {
close();
} catch (IOException e) {
Logger.getLogger("org.appconn").log(Level.CONFIG, "interrupt", e);
}
}
@Override
public void close() throws IOException {
selector.close();
channel.close();
super.interrupt();
}
private class ClientHandler implements Handler {
private final SocketChannel channel;
private ClientHandler(SocketChannel channel) {
this.channel = channel;
}
@Override
public synchronized void handle() {
try {
readBuffer.read();
while (readBuffer.hasRemaining()) {
int position = readBuffer.getInt();
MethodReturn methodReturn = remove(position);
if (methodReturn != null) {
if (readBuffer.get() == Writer.IS_RETURN) methodReturn.setReturn(readBuffer);
else {
String className = TypeReader.STRING_READER.get(readBuffer);
Throwable throwable = TypeReader.THROWABLE_READER.get(readBuffer);
Exception exception = (Exception) Class.forName(className).getConstructor(String.class).newInstance(throwable.getMessage());
exception.setStackTrace(throwable.getStackTrace());
methodReturn.setException(exception);
}
} else {
Logger.getLogger("org.appconn").log(Level.WARNING, "null methodReturn position " + position);
channel.close();
}
}
} catch (Exception e) {
Logger.getLogger("org.appconn").log(Level.WARNING, e, e::getMessage);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy