-
-
Notifications
You must be signed in to change notification settings - Fork 110
Expand file tree
/
Copy pathTcpSocketServer.java
More file actions
133 lines (117 loc) · 4.67 KB
/
TcpSocketServer.java
File metadata and controls
133 lines (117 loc) · 4.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package com.asterinet.react.tcpsocket;
import android.content.Context;
import com.facebook.react.bridge.ReadableMap;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ssl.SSLServerSocketFactory;
public final class TcpSocketServer extends TcpSocket {
private final TcpEventListener mReceiverListener;
private final ExecutorService listenExecutor;
private final ConcurrentHashMap<Integer, TcpSocket> socketClients;
private final boolean isTLS;
private ServerSocket serverSocket;
private int clientSocketIds;
public TcpSocketServer(final Context context, final ConcurrentHashMap<Integer, TcpSocket> socketClients, final TcpEventListener receiverListener, final Integer id,
final ReadableMap options) throws IOException, GeneralSecurityException {
super(id);
listenExecutor = Executors.newSingleThreadExecutor();
// Get data from options
int port = options.getInt("port");
String address = options.getString("host");
this.socketClients = socketClients;
clientSocketIds = (1 + getId()) * 1000;
// Get the addresses
InetAddress localInetAddress = InetAddress.getByName(address);
// Create the socket
// Check if TLS
ReadableMap tlsOptions = options.getMap("tls");
if (tlsOptions != null) {
String keystoreResourceUri = tlsOptions.getString("keystore");
assert keystoreResourceUri != null;
String passphrase = tlsOptions.hasKey("passphrase") ? tlsOptions.getString("passphrase") : null;
SSLServerSocketFactory ssf = SSLCertificateHelper.createServerSocketFactory(context, keystoreResourceUri, passphrase);
serverSocket = ssf.createServerSocket(port, 50, localInetAddress);
isTLS = true;
// ((SSLServerSocket) serverSocket).setNeedClientAuth(true);
} else {
serverSocket = new ServerSocket(port, 50, localInetAddress);
isTLS = false;
}
// setReuseAddress
try {
boolean reuseAddress = options.getBoolean("reuseAddress");
serverSocket.setReuseAddress(reuseAddress);
} catch (Exception e) {
// Default to true
serverSocket.setReuseAddress(true);
}
mReceiverListener = receiverListener;
listen();
}
public ServerSocket getServerSocket() {
return serverSocket;
}
private void addClient(Socket socket) {
int clientId = getClientId();
TcpSocketClient socketClient = new TcpSocketClient(mReceiverListener, clientId, socket);
socketClients.put(clientId, socketClient);
if (isTLS) {
mReceiverListener.onSecureConnection(getId(), clientId, socket);
} else {
mReceiverListener.onConnection(getId(), clientId, socket);
}
socketClient.startListening();
}
/**
* Next ID for a client socket
*
* @return The next ID for a client socket
*/
private int getClientId() {
return clientSocketIds++;
}
private void listen() {
TcpListenTask tcpListenTask = new TcpListenTask(this, mReceiverListener);
listenExecutor.execute(tcpListenTask);
}
public void close() {
try {
// close the socket
if (serverSocket != null && !serverSocket.isClosed()) {
serverSocket.close();
mReceiverListener.onClose(getId(), null);
serverSocket = null;
}
} catch (IOException e) {
mReceiverListener.onClose(getId(), e);
}
}
private static class TcpListenTask implements Runnable {
private final TcpEventListener receiverListener;
private final TcpSocketServer server;
private TcpListenTask(TcpSocketServer server, TcpEventListener receiverListener) {
this.server = server;
this.receiverListener = receiverListener;
}
@Override
public void run() {
ServerSocket serverSocket = server.getServerSocket();
try {
while (!serverSocket.isClosed()) {
Socket socket = serverSocket.accept();
server.addClient(socket);
}
} catch (IOException e) {
if (!serverSocket.isClosed()) {
receiverListener.onError(server.getId(), e);
}
}
}
}
}