Can't connect to local socketIO nodejs server on android - java

I have made a basic nodejs server that console logs when a user connects to the server. i am using socket io for this because i wanna make a chat application. On my android side im trying to create a connection to this local server but i never get the console log when i try and socket.connected stays on false. also never get a error or something when trying to connect
I have tried some examples from the internet. i got 1 example working deleted everything that i didnt use and it still works. i copy paste from that example to my own project and still didn't work.
This is the example i used.
Here is the code of my project
Node JS:
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Android:
public class MainActivity extends Activity {
private Socket socket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ChatApplication app = (ChatApplication) getApplication();
socket = app.getSocket();
socket.connect();
}
}
ChatApplication class:
public class ChatApplication extends Application {
private Socket mSocket;
{
try {
mSocket = IO.socket("http://192.168.0.109:3000");
} catch (Exception e) {
Log.e("Error", e.toString());
}
}
public Socket getSocket() {
return mSocket;
}
}

Android Studio emulator usually prevents localhost connections, I'm not sure if this happened in your case, but it has happened to me. Try popping out your Logcat in Android Studio and see if you can find something that indicates that the localhost connection got denied.
Not sure if this is it, but you should check.

Related

I keep getting 404 error in socket.io connection

I am trying to connect my android app to NodeJS server.
ANDROID PART
First I include the Socket.io library to my dependency
implementation('io.socket:socket.io-client:2.0.0') {
exclude group: 'org.json', module: 'json'
}
My JAVA code
//all variables used are initialized, defined and working perfectly
try {
socket = IO.socket(socketUrl);
socket.on(Socket.EVENT_CONNECT, args -> runOnUiThread(() -> socket.emit("connected", true)));
socket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
}
SERVER SIDE
var express = require('express'),
app = express(),
socket = require('socket.io'),
router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
var server = app.listen(4000, function(){
console.log('listening for requests on port 4000,');
});
let io = socket(server);
io.on('connection', function(socket){
console.log(`${socket.id} is connected`);
});
module.exports = router;
Now the problem is after starting the Server, and I try to connect my android app to it, I keep getting an error from Socket.io connection, like the image below
I have searched SO for solution and I get multiple answers relating to this, but I still keep getting the same error
My Socket.io version is 8.5.5
you can not use socket directly via express, here is the documentation.
try this code instead.
var express = require('express'),
app = express()
const httpServer = require("http").createServer(app);
const io = require("socket.io")(httpServer);
router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
io.on('connection', function(socket){
console.log(`${socket.id} is connected`);
});
httpServer.listen(4000, function(){
console.log('listening for requests on port 4000,');
});
module.exports = router;

Socket.io connection doesn't work for multiple fragments

I am creating a project with socket.io. It works really fine as long as there is just one fragment. However as I add more fragments in main activity, it starts creating multiple connections, which i think is not a good idea.
At first I connected to socket.io directly from fragments but that was creating one connection for each fragment. So I created a connection in Application class and used that in fragments which instantly solved multiple connection problem. But now a new problem has occurred.
In case of internet disconnection and reconnection, fragment doesn't get reestablished connection from Application class. I have been trying for over a week but no solution. strange thing is, i searched on internet and stackoverflow but not a single such question is ever asked.
here is connection code in Application class
synchronized public Socket getSocket() {
if (mSocket == null) {
try {
IO.Options opts = new IO.Options();
opts.reconnection = true;
opts.reconnectionDelay = 1000;
mSocket = IO.socket("http://ddbharti.in", opts);
mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(TAG, "EVENT_CONNECT");
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(TAG, "EVENT_DISCONNECT");
}
}).on(Socket.EVENT_ERROR, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(TAG, "error");
}
});
mSocket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
return mSocket;
}
and this is how each fragment is connecting
socket = application.getSocket();
socket.emit("tag", tag);
If internet is working fine, this setup works flawlessly, loads in 300 milliseconds. However as i disconnect/reconnect internet or I keep internet disconnected and start the app and then connect to internet. Connection in Application class connects quickly, but due to some reason connection in current fragment just doesn't get it.
If i switch fragments then it starts listening to connection from Application class again.
So am i missing something here? How can i force fragment to get connection from application class again in case of reconnection without reloading whole fragment?
Any help is greatly appreciated.
So i created an event listner to listen to socket connection status and show ui accordingly. Just one connect with event listner was all that was needed.

Java FTPClient: Getting "Connection reset by peer" when calling getReply()

I was recently trying to connect to a FTP server via a mobile application.
I'm able to connect to my server and check if it's connected (which it is).
Next thing is to login with a username and password following with a passive mode setup. Last thing I did was get the reply code from the server, but when my application is running, my screens goes black. When I reopen my application it says "recv failed: ECONNREST (Connection reset by peer)" as the error message I output. Here is my code:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
ftpClient = new FTPClient();
textView = (TextView)findViewById(R.id.textView_id);
textView2 = (TextView)findViewById(R.id.textView2_id);
textView3 = (TextView)findViewById(R.id.textView3_id);
textView4 = (TextView)findViewById(R.id.textView4_id);
textView5 = (TextView)findViewById(R.id.textView5_id);
try{
ftpClient.connect(ip, port);
boolean connectSucces = ftpClient.isConnected();
ftpClient.login(userName,passWord);
ftpClient.enterLocalPassiveMode();
ftpClient.getReply();
int connectionMode = ftpClient.getDataConnectionMode();
if(connectionMode == ftpClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE) {
textView.setText("Connected: " + connectSucces + " ConnectionMode: " + connectionMode);
}
}catch(Exception e){
textView.setText(e.getMessage());
}
}
Am I missing something?
I believe it's the call to getReply() that deadlocks your code.
You didn't send any command to which the server should reply, so the client waits for the response until it or the server times out.
The latter happened probably, that's why the connection was closed/reset by the server.
You generally do not call getReply() yourself. In most cases it's called internally by the FTPClient for you:
Only use this method if you are implementing your own FTP client or if you need to fetch a secondary response from the FTP server.
While I have no experience with Android development, from the symptoms and your code, I assume you connect to the FTP server from a GUI thread, what is rather a bad practice. That would explain why the screen goes blank while you wait.

Socket android client PC server

I have problem to connect my android client to my PC Server
here there are the codes
-->PC SERVER:
public class Server {
public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException
{
ServerSocket server = new ServerSocket(4444);
System.out.println("Waiting for clients to connect...");
while (true)
{
Socket s = server.accept();
InetAddress clientAddress = s.getInetAddress();
System.out.println("Incoming connection from: " + clientAddress.getHostName() + "[" + clientAddress.getHostAddress() + "]");
s.close();
}
}
}
--->ANDROID CLIENT:
public class Main extends Activity {
Button b;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b = (Button)findViewById(R.id.connect);
b.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View arg0) {
try {
Socket client = new Socket("10.0.2.2", 4444); //connect to server
client.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
When on my android device i click the button in my server program(PC) doesn't view device connect...why? i've tried to insert
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
into my AndroidManifest but when i click on button program crash
Android device and PC are connected to same network(router DSL).
Help me please
10.0.2.2 is an address that is used by your app running in an emulator to connect with a server running on your pc. The emulator is on the same pc. If you use a real devive you have to use the (W)LAN address of your pc which is in the same WLAN as your device. Often something like 192.168.0.12. Find out with ipconfig.
The address you are using is 10.0.2.2, which is non routable as private.
You should use an address that your device can resolve. Either a DNS name published in a DNS accessible from your phone (so a public one) or a routable IP. Your server should be reachable from the public network, which is unlikely to be the case of your PC unless you have specifically took care of that - I am not sure of what you mean by this:
Android device and PC are connected to same network(router DSL)
Please have a look at the exception that is thrown on phone side and edit your post with the resulting stack trace. It will help to dig into this further.
Your socket declaration should be as follow :
Socket client = new Socket(10.0.2.2, 4444); //Quotes removed

Writing to an AsynchronousSocketChannel and processing the data in an Event-based way

I'm trying to figure out how to send data between sockets in Java (this is part of a bigger project and I'll get back and answer my previous two questions related to that once I can resolve this..). I would like to connect a client and a server socket asynchronously in Java, and then send messages between them, and get a callback, say, when I have sent a message from the client to the server.
I think I have managed to get the set-up working. Here is my code:
private AsynchronousServerSocketChannel socListener;
private AsycnchrnonousSocketChannel socClient;
//This is the GUI callback for the button that initiates the socket server
private void button_StartSocketServerActionPerformed(ava.awt.event.ActionEvent evt)
{
try{
InetAddress ipLocal= InetAddress.getLocalHost();
InetSocketAddress ipSocket=new InetSocketAddress(ipLocal,8221);
m_socListener= AsynchronousServerSocketChannel.open().bind(ipSocket);
m_socListener.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>()
{
#Override
public void completed(AsynchronousSocketChannel ch, Void att)
{
// accept the next connection
m_socListener.accept(null, this);
// handle this connection
}
#Override
public void failed(Throwable exc, Void att) { }
}
);
}
catch (Exception e){
}
}
//This is the GUI callback for the button that initiates the client socket
private void button_StartClientSocketActionPerformed(java.awt.event.ActionEvent evt)
{
try
{
socClient=AsynchronousSocketChannel.open();
InetAddress ipLocal= InetAddress.getLocalHost();
InetSocketAddress ipSocket=new InetSocketAddress(ipLocal,8221);
socClient.connect(ipSocket, null, new CompletionHandler<Void,Void>()
{
#Override
public void completed(Void att1, Void att2)
{
// handle this connection
}
#Override
public void failed(Throwable exc, Void att) {}
}
);
}
catch (Exception e){
}
}
I'm including the server and the client in the same file for simplicity of testing.
So supposing the connection is successfully established, and I have a process on a timer (say) that was writing data to the server socket, I'd like to have the client socket 'listen' for this new data being sent from the server and then generate a callback when a write occurs (without doing something like periodically checking via a timer and a while loop to check that whether new data has been added). This is accomplishable in C# and a nice tutorial is available at:
http://www.developerfusion.com/article/3918/socket-programming-in-c-part-1/2/
Any tips on how to do this would be greatly appreciated. Thanks!
Chris
You could use RMI to accomplish that, the documentation can be found there:
http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136424.html
With this, your server could notify your client as much as you need.

Categories