1010import java .io .*;
1111import java .net .Socket ;
1212
13+ /**
14+ * Capacitor plugin that provides raw TCP socket functionality.
15+ * Implements methods to connect, send, receive, and disconnect.
16+ */
1317@ CapacitorPlugin (name = "SocketPlugin" )
1418public class SocketPlugin extends Plugin {
1519 private Socket socket ;
1620 private BufferedReader reader ;
1721 private BufferedWriter writer ;
22+ private boolean isConnected = false ;
1823
1924 @ PluginMethod
2025 public void connect (PluginCall call ) {
2126 String ip = call .getString ("ip" );
2227 int port = call .getInt ("port" );
28+
29+ // Validate inputs
30+ if (ip == null || ip .isEmpty ()) {
31+ call .reject ("IP address is required" );
32+ return ;
33+ }
34+
35+ if (port <= 0 || port > 65535 ) {
36+ call .reject ("Invalid port number" );
37+ return ;
38+ }
39+
40+ // Prevent duplicate connections
41+ if (socket != null && !socket .isClosed ()) {
42+ call .reject ("Already connected; please disconnect first" );
43+ return ;
44+ }
45+
2346 try {
2447 socket = new Socket (ip , port );
48+ socket .setSoTimeout (30_000 ); // 30s timeout
2549 reader = new BufferedReader (new InputStreamReader (socket .getInputStream ()));
2650 writer = new BufferedWriter (new OutputStreamWriter (socket .getOutputStream ()));
51+ isConnected = true ;
2752 JSObject ret = new JSObject ();
2853 ret .put ("success" , true );
2954 call .resolve (ret );
3055 } catch (Exception e ) {
56+ closeResources ();
3157 call .reject ("Connection failed: " + e .getMessage ());
3258 }
3359 }
3460
35- @ PluginMethod
61+ @ PluginMethod
3662 public void send (PluginCall call ) {
3763 String data = call .getString ("data" );
64+
65+ // Validate input
66+ if (data == null ) {
67+ call .reject ("Data is required" );
68+ return ;
69+ }
70+
71+ // Check connection state
72+ if (socket == null || socket .isClosed () || !isConnected ) {
73+ call .reject ("Not connected to any server" );
74+ return ;
75+ }
76+
3877 try {
3978 writer .write (data );
4079 writer .flush ();
4180 JSObject ret = new JSObject ();
4281 ret .put ("success" , true );
4382 call .resolve (ret );
4483 } catch (Exception e ) {
84+ closeResources ();
85+ isConnected = false ;
4586 call .reject ("Send failed: " + e .getMessage ());
4687 }
4788 }
@@ -61,12 +102,36 @@ public void receive(PluginCall call) {
61102 @ PluginMethod
62103 public void disconnect (PluginCall call ) {
63104 try {
64- if (socket != null ) socket .close ();
105+ closeResources ();
106+ isConnected = false ;
65107 JSObject ret = new JSObject ();
66108 ret .put ("success" , true );
67109 call .resolve (ret );
68110 } catch (Exception e ) {
69111 call .reject ("Disconnect failed: " + e .getMessage ());
70112 }
71113 }
114+
115+ /**
116+ * Helper method to close all resources and clean up state
117+ */
118+ private void closeResources () {
119+ try {
120+ if (reader != null ) {
121+ reader .close ();
122+ reader = null ;
123+ }
124+ if (writer != null ) {
125+ writer .close ();
126+ writer = null ;
127+ }
128+ if (socket != null ) {
129+ socket .close ();
130+ socket = null ;
131+ }
132+ } catch (IOException e ) {
133+ // Log but continue cleanup
134+ getContext ().getActivity ().runOnUiThread (() ->
135+ Log .e ("SocketPlugin" , "Error closing resources" , e ));
136+ }
72137}
0 commit comments