Java tutorial
/* Copyright (c) 2011 Danish Maritime Authority. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package dk.dma.ais.bus.provider; import dk.dma.ais.bus.AisBusProvider; import dk.dma.ais.bus.tcp.IClientStoppedListener; import dk.dma.ais.bus.tcp.TcpClient; import dk.dma.ais.bus.tcp.TcpClientConf; import dk.dma.ais.bus.tcp.TcpReadClient; import dk.dma.ais.packet.AisPacket; import net.jcip.annotations.ThreadSafe; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; /** * Round robin TCP client provider */ @ThreadSafe public final class TcpClientProvider extends AisBusProvider implements Runnable, Consumer<AisPacket>, IClientStoppedListener { private static final Logger LOG = LoggerFactory.getLogger(TcpClientProvider.class); private TcpReadClient readClient; private TcpClientConf clientConf = new TcpClientConf(); private List<String> hostsPorts = new ArrayList<>(); private int reconnectInterval = 10; private int timeout = 10; private List<String> hostnames = new ArrayList<>(); private List<Integer> ports = new ArrayList<>(); private int currentHost = -1; private volatile Socket socket; public TcpClientProvider() { super(); } @Override public void run() { setNotConnected(); while (true) { socket = new Socket(); // Get next host and port selectHost(); String host = hostnames.get(currentHost); int port = ports.get(currentHost); // Connect try { InetSocketAddress address = new InetSocketAddress(host, port); LOG.info("Connecting to " + host + ":" + port + " ..."); socket.connect(address); socket.setKeepAlive(true); if (timeout > 0) { socket.setSoTimeout(timeout * 1000); } setConnected(); // Start client readClient = new TcpReadClient(this, this, socket, clientConf); readClient.start(); // Wait for client to loose connection readClient.join(); readClient = null; } catch (IOException e) { LOG.info(getName() + ": connection error: " + e.getMessage()); } catch (InterruptedException e) { readClient.cancel(); break; } setNotConnected(); try { LOG.info("Waiting to reconnect"); Thread.sleep(reconnectInterval * 1000); } catch (InterruptedException e) { break; } } setStopped(); } @Override public void accept(AisPacket packet) { push(packet); } @Override public synchronized void start() { // Start self as thread Thread t = new Thread(this); setThread(t); t.start(); super.start(); } @Override public void cancel() { // Close socket Socket s = socket; if (s != null) { try { s.close(); } catch (IOException ignore) { } } getThread().interrupt(); try { getThread().join(THREAD_STOP_WAIT_MAX); } catch (InterruptedException e) { e.printStackTrace(); } setStopped(); } @Override public synchronized void init() { for (String hostPort : hostsPorts) { String[] parts = StringUtils.split(hostPort, ':'); hostnames.add(parts[0]); ports.add(Integer.parseInt(parts[1])); } super.init(); } public List<String> getHostsPorts() { return hostsPorts; } public void setHostsPorts(List<String> hostsPorts) { this.hostsPorts = hostsPorts; } public void setClientConf(TcpClientConf clientConf) { this.clientConf = clientConf; } public void setTimeout(int timeout) { this.timeout = timeout; } public void setReconnectInterval(int reconnectInterval) { this.reconnectInterval = reconnectInterval; } @Override public void clientStopped(TcpClient client) { } private void selectHost() { currentHost = (currentHost + 1) % hostnames.size(); } }