]> git.basschouten.com Git - openhab-addons.git/blob
328f246d74fefaa6213bd0edb4b0c35f37bba45c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.homematic.internal.communicator.client;
14
15 import java.io.IOException;
16 import java.net.InetSocketAddress;
17 import java.net.Socket;
18 import java.util.HashMap;
19 import java.util.Map;
20
21 import org.openhab.binding.homematic.internal.common.HomematicConfig;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 /**
26  * Simple socket cache class.
27  *
28  * @author Gerhard Riegler - Initial contribution
29  */
30 public class SocketHandler {
31     private final Logger logger = LoggerFactory.getLogger(SocketHandler.class);
32
33     private Map<Integer, SocketInfo> socketsPerPort = new HashMap<>();
34     private HomematicConfig config;
35
36     public SocketHandler(HomematicConfig config) {
37         this.config = config;
38     }
39
40     /**
41      * Returns a socket for the given port, (re)creates it if required.
42      */
43     public Socket getSocket(int port) throws IOException {
44         SocketInfo socketInfo = socketsPerPort.get(port);
45         if (socketInfo == null) {
46             logger.trace("Creating new socket for port {}", port);
47             Socket socket = new Socket();
48             socket.setSoTimeout(config.getTimeout() * 1000);
49             socket.setReuseAddress(true);
50             socket.connect(new InetSocketAddress(config.getGatewayAddress(), port), socket.getSoTimeout());
51             socketInfo = new SocketInfo(socket);
52             socketsPerPort.put(port, socketInfo);
53         } else {
54             boolean isMaxAliveReached = System.currentTimeMillis()
55                     - socketInfo.getCreated() > (config.getSocketMaxAlive() * 1000);
56
57             if (isMaxAliveReached) {
58                 logger.debug("Max alive time reached for socket on port {}", port);
59                 removeSocket(port);
60                 return getSocket(port);
61             }
62             logger.trace("Returning socket for port {}", port);
63         }
64         return socketInfo.getSocket();
65     }
66
67     /**
68      * Removes the socket for the given port from the cache.
69      */
70     public void removeSocket(int port) {
71         SocketInfo socketInfo = socketsPerPort.get(port);
72         if (socketInfo != null) {
73             logger.trace("Closing Socket on port {}", port);
74             socketsPerPort.remove(port);
75             closeSilent(socketInfo.getSocket());
76         }
77     }
78
79     /**
80      * Removes all cached sockets.
81      */
82     public void flush() {
83         synchronized (SocketHandler.class) {
84             Integer[] portsToRemove = socketsPerPort.keySet().toArray(new Integer[0]);
85             for (Integer key : portsToRemove) {
86                 removeSocket(key);
87             }
88         }
89     }
90
91     /**
92      * Silently closes the given socket.
93      */
94     private void closeSilent(Socket socket) {
95         try {
96             socket.close();
97         } catch (IOException e) {
98             // ignore
99         }
100     }
101 }