Skip to content

Commit 5284061

Browse files
authored
refactor(Android): Remove android dependencies (Rapsssito#132)
1 parent 5529f45 commit 5284061

File tree

4 files changed

+106
-109
lines changed

4 files changed

+106
-109
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ local.properties
3333
android/gradle/
3434
android/gradlew
3535
android/gradlew.bat
36+
.project
37+
.classpath
38+
.settings
3639

3740
# node.js
3841
#

android/src/main/java/com/asterinet/react/tcpsocket/TcpReceiverTask.java

Lines changed: 0 additions & 64 deletions
This file was deleted.

android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,31 @@
55

66
import com.facebook.react.bridge.ReadableMap;
77

8+
import java.io.BufferedInputStream;
89
import java.io.IOException;
910
import java.net.InetAddress;
1011
import java.net.InetSocketAddress;
1112
import java.net.Socket;
1213
import java.security.GeneralSecurityException;
14+
import java.util.Arrays;
1315
import java.util.concurrent.ExecutorService;
1416
import java.util.concurrent.Executors;
1517

1618
import javax.net.SocketFactory;
1719
import javax.net.ssl.SSLSocket;
1820
import javax.net.ssl.SSLSocketFactory;
1921

20-
import androidx.annotation.NonNull;
21-
import androidx.annotation.Nullable;
22-
2322
class TcpSocketClient extends TcpSocket {
2423
private final ExecutorService listenExecutor;
2524
private final ExecutorService writeExecutor;
2625
private final TcpEventListener receiverListener;
27-
private final TcpReceiverTask receiverTask;
26+
private TcpReceiverTask receiverTask;
2827
private Socket socket;
2928

30-
TcpSocketClient(@NonNull final TcpEventListener receiverListener, @NonNull final Integer id, @Nullable final Socket socket) {
29+
TcpSocketClient(TcpEventListener receiverListener, Integer id, Socket socket) {
3130
super(id);
3231
listenExecutor = Executors.newSingleThreadExecutor();
3332
writeExecutor = Executors.newSingleThreadExecutor();
34-
receiverTask = new TcpReceiverTask(this, receiverListener);
3533
this.socket = socket;
3634
this.receiverListener = receiverListener;
3735
}
@@ -40,7 +38,7 @@ public Socket getSocket() {
4038
return socket;
4139
}
4240

43-
public void connect(@NonNull final Context context, @NonNull final String address, @NonNull final Integer port, @NonNull final ReadableMap options, @Nullable final Network network) throws IOException, GeneralSecurityException {
41+
public void connect(Context context, String address, final Integer port, ReadableMap options, Network network) throws IOException, GeneralSecurityException {
4442
if (socket != null) throw new IOException("Already connected");
4543
final boolean isTls = options.hasKey("tls") && options.getBoolean("tls");
4644
if (isTls) {
@@ -80,6 +78,7 @@ public void connect(@NonNull final Context context, @NonNull final String addres
8078
}
8179

8280
public void startListening() {
81+
receiverTask = new TcpReceiverTask(this, receiverListener);
8382
listenExecutor.execute(receiverTask);
8483
}
8584

@@ -147,4 +146,62 @@ public void pause() {
147146
public void resume() {
148147
receiverTask.resume();
149148
}
149+
150+
/**
151+
* This is a specialized Runnable that receives data from a socket in the background, and
152+
* notifies it's listener when data is received. This is not threadsafe, the listener
153+
* should handle synchronicity.
154+
*/
155+
private static class TcpReceiverTask implements Runnable {
156+
157+
private final TcpSocketClient clientSocket;
158+
private final TcpEventListener receiverListener;
159+
private boolean paused = false;
160+
161+
public TcpReceiverTask(TcpSocketClient clientSocket, TcpEventListener receiverListener) {
162+
this.clientSocket = clientSocket;
163+
this.receiverListener = receiverListener;
164+
}
165+
166+
/**
167+
* An infinite loop to block and read data from the socket.
168+
*/
169+
@Override
170+
public void run() {
171+
int socketId = clientSocket.getId();
172+
Socket socket = clientSocket.getSocket();
173+
byte[] buffer = new byte[16384];
174+
try {
175+
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
176+
while (!socket.isClosed()) {
177+
int bufferCount = in.read(buffer);
178+
waitIfPaused();
179+
if (bufferCount > 0) {
180+
receiverListener.onData(socketId, Arrays.copyOfRange(buffer, 0, bufferCount));
181+
} else if (bufferCount == -1) {
182+
clientSocket.destroy();
183+
}
184+
}
185+
} catch (IOException | InterruptedException ioe) {
186+
if (receiverListener != null && !socket.isClosed()) {
187+
receiverListener.onError(socketId, ioe.getMessage());
188+
}
189+
}
190+
}
191+
192+
public synchronized void pause() {
193+
paused = true;
194+
}
195+
196+
public synchronized void resume() {
197+
paused = false;
198+
notify();
199+
}
200+
201+
private synchronized void waitIfPaused() throws InterruptedException {
202+
while (paused) {
203+
wait();
204+
}
205+
}
206+
}
150207
}
Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package com.asterinet.react.tcpsocket;
22

3-
import android.annotation.SuppressLint;
4-
import android.os.AsyncTask;
5-
63
import com.facebook.react.bridge.ReadableMap;
74

85
import java.io.IOException;
@@ -14,39 +11,16 @@
1411
import java.util.concurrent.Executors;
1512

1613
public final class TcpSocketServer extends TcpSocket {
17-
private ServerSocket serverSocket;
1814
private final TcpEventListener mReceiverListener;
19-
private int clientSocketIds;
20-
private final ExecutorService executorService;
15+
private final ExecutorService listenExecutor;
2116
private final ConcurrentHashMap<Integer, TcpSocket> socketClients;
22-
23-
@SuppressLint("StaticFieldLeak")
24-
private final AsyncTask listening = new AsyncTask() {
25-
@Override
26-
protected Void doInBackground(Object[] objects) {
27-
try {
28-
while (!isCancelled() && !serverSocket.isClosed()) {
29-
Socket socket = serverSocket.accept();
30-
int clientId = getClientId();
31-
TcpSocketClient socketClient = new TcpSocketClient(mReceiverListener, clientId, socket);
32-
socketClients.put(clientId, socketClient);
33-
mReceiverListener.onConnection(getId(), clientId, socket);
34-
socketClient.startListening();
35-
}
36-
} catch (IOException e) {
37-
if (!serverSocket.isClosed()) {
38-
mReceiverListener.onError(getId(), e.getMessage());
39-
}
40-
}
41-
return null;
42-
}
43-
};
44-
17+
private ServerSocket serverSocket;
18+
private int clientSocketIds;
4519

4620
public TcpSocketServer(final ConcurrentHashMap<Integer, TcpSocket> socketClients, final TcpEventListener receiverListener, final Integer id,
4721
final ReadableMap options) throws IOException {
4822
super(id);
49-
this.executorService = Executors.newFixedThreadPool(1);
23+
listenExecutor = Executors.newSingleThreadExecutor();
5024
// Get data from options
5125
int port = options.getInt("port");
5226
String address = options.getString("host");
@@ -73,6 +47,14 @@ public ServerSocket getServerSocket() {
7347
return serverSocket;
7448
}
7549

50+
private void addClient(Socket socket) {
51+
int clientId = getClientId();
52+
TcpSocketClient socketClient = new TcpSocketClient(mReceiverListener, clientId, socket);
53+
socketClients.put(clientId, socketClient);
54+
mReceiverListener.onConnection(getId(), clientId, socket);
55+
socketClient.startListening();
56+
}
57+
7658
/**
7759
* Next ID for a client socket
7860
*
@@ -83,18 +65,12 @@ private int getClientId() {
8365
}
8466

8567
private void listen() {
86-
//noinspection unchecked
87-
listening.executeOnExecutor(executorService);
68+
TcpListenTask tcpListenTask = new TcpListenTask(this, mReceiverListener);
69+
listenExecutor.execute(tcpListenTask);
8870
}
8971

9072
public void close() {
9173
try {
92-
if (!listening.isCancelled()) {
93-
// stop the receiving task
94-
listening.cancel(true);
95-
executorService.shutdown();
96-
}
97-
9874
// close the socket
9975
if (serverSocket != null && !serverSocket.isClosed()) {
10076
serverSocket.close();
@@ -105,4 +81,29 @@ public void close() {
10581
mReceiverListener.onClose(getId(), e.getMessage());
10682
}
10783
}
84+
85+
private static class TcpListenTask implements Runnable {
86+
private final TcpEventListener receiverListener;
87+
private final TcpSocketServer server;
88+
89+
private TcpListenTask(TcpSocketServer server, TcpEventListener receiverListener) {
90+
this.server = server;
91+
this.receiverListener = receiverListener;
92+
}
93+
94+
@Override
95+
public void run() {
96+
ServerSocket serverSocket = server.getServerSocket();
97+
try {
98+
while (!serverSocket.isClosed()) {
99+
Socket socket = serverSocket.accept();
100+
server.addClient(socket);
101+
}
102+
} catch (IOException e) {
103+
if (!serverSocket.isClosed()) {
104+
receiverListener.onError(server.getId(), e.getMessage());
105+
}
106+
}
107+
}
108+
}
108109
}

0 commit comments

Comments
 (0)