Why java socket.io emit is fail - java

i'm creating android application with Socket.io and node.js server.
My js server:
var http = require('http');
var server = http.createServer(function(req, res) {
});
var mysql = require('mysql');
var db = mysql.createConnection({
host:,
port:,
user:,
password:,
database:
});
var resultconnection = "";
db.connect(function(err){
if (err) {
resultconnection = err;
}
});
var io = require('socket.io').listen(server);
io.on('connection',function(socket){
console.log('Connected!');
socket.on("createaccount", function(data){
console.log('Create account executed.');
if(resultconnection != ""){
db.query("INSERT INTO USER (USERNAME, PASSWORD, EMAIL, BIRTHDATE) VALUES('"+data["username"]+"', SHA1('"+data["password"]+"'), '"+data["email"]+"', "+data["birthdate"]+"')");
resultconnection = "OK";
}
socket.emit('response', {"response": resultconnection});
});
});
server.listen(8080);
Android client(java):
try {
socket = IO.socket("http://localhost:8080");
socket.on("response", new Emitter.Listener() {
#Override
public void call(Object... args) {
JSONObject obj = (JSONObject) args[0];
try {
result = obj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
socket.connect();
JSONObject createUser = new JSONObject();
try {
createUser.put("username", username);
createUser.put("password", password);
createUser.put("email", email);
createUser.put("birthdate", datanasc);
} catch (JSONException e) {
e.printStackTrace();
}
socket.emit("createaccount", "");
} catch (URISyntaxException e) {
result = e.getMessage();
}
Console.log("Connected") is running but when I run the socket.emit("createaccount") the client does not run on the server.

I think the server IP you gave in the client code is not correct. It is trying to connect to the localhost of your Android device while your server is running on some other remote system.
Try changing the server IP in the following snippet(ideally this should be something other than localhost):
try {
socket = IO.socket("<server_IP:server_PORT");
socket.on("response", new Emitter.Listener() {
#Override
public void call(Object... args) {
JSONObject obj = (JSONObject) args[0];
try {
result = obj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
socket.connect();
JSONObject createUser = new JSONObject();
try {
createUser.put("username", username);
createUser.put("password", password);
createUser.put("email", email);
createUser.put("birthdate", datanasc);
} catch (JSONException e) {
e.printStackTrace();
}
socket.emit("createaccount", "");
} catch (URISyntaxException e) {
result = e.getMessage();
}

There are significant structural problems with how your server is designed:
You're trying to save resultconnection in a module global. That means you can only ever have one socket.io client connection that will work properly. The second connection will see the resultconnection from the previous client connection. There's just no way this is a proper way to do things. It could possibly work if you never ever had more than one client connect to your server - not just one client at a time, but one client all time.
The way you handle the async database operation in the createaccount message handler is just wrong. You are trying to .emit() the resultconnection back to the client before it has been set.
Your error handling for the db.connect() call does not seem correct. When you can't connect to the database you need to take some action, not just set a variable as such and proceed on as if nothing is wrong. Even that variable you set is being used wrong later. You're checking to see if you had an error on the connect and if you did, then you're trying to do a database operation. Besides just a messed up design, this logic is even backwards.
To think about how to fix the first issue, you need to explain what you're trying to do with this statement:
if(resultconnection != ""){
because that will need to be done a different way. You can't just save global state in your server and expect that to represent the state of any incoming connection.
How to fix the second issue will depend upon what is done for the first issue.
How to fix the third issue involves some design decisions about what to do with your server when you can't connect to the database (shut-down, retry, log, etc...).

Related

Mqtt Paho Client Connection always open

i have created mqtt connection suscribeData() as follows to receive data 24/7 from multiple devices
#RequestMapping("/suscribe")
#ResponseBody
public String suscribeData(){
connOpt= new MqttConnectOptions();
connOptPublish= new MqttConnectOptions();
boolean result=false;
int retry=0;
while(!result){
try{
result=initializeMqTTParameters(retry);
retry++;
if(!result){
Thread.sleep(1000);
}
}catch(Exception ex){
}
if(retry>10){
return "mqtterror";
}
}
suscribeReceivedData("DATA/#",2);
Calendar cal=TimeZoneJu.getCalenderInstance();
ModemOnlineStatus status=new ModemOnlineStatus();
status.setActiondate(cal.getTime());
status.setActiontime(cal.getTime());
status.setModemid("mqttreceive");
status.setRemark("online");
status.setStatus(true);
try{
service.checkAndInsertModemStatus(true, status);
}catch(Exception ex1){
}
return "ok";
}
checkAndInsertModemStatus() function is used to save the online offline state of connection i check the connection from another url with cronjobs.
and following is my initializeMqTTParameters
public boolean initializeMqTTParameters(int retry){
String clientID = M2MIO_THING;
connOpt = new MqttConnectOptions();
connOpt.setCleanSession(false);
connOpt.setUserName(M2MIO_USERNAME);
connOpt.setPassword(M2MIO_PASSWORD_MD5.toCharArray());
connOpt.setWill("WILL/mqttreceive", "mqttreceive:disconnected".getBytes(), 2, true);
try {
if(retry%2==0){
MQTTReceive.myClient = new MqttClient(BROKER_URL, "mqtt_virtual_received_sus_1");
}else{
MQTTReceive.myClient = new MqttClient(BROKER_URL, "mqtt_virtual_received_sus_2");
}
MQTTReceive.myClient.setCallback(this);
MQTTReceive.myClient.connect(connOpt);
} catch (MqttException e) {
System.out.println(e.getMessage());
return false;
}
return true;
}
on connectionLost i am trying update status in database and try reconnect
#Override
public void connectionLost(Throwable ex) {
System.out.println("Mqtt Received Connection Lost"+ex.getMessage());
Calendar cal=TimeZoneJu.getCalenderInstance();
ModemOnlineStatus status=new ModemOnlineStatus();
status.setActiondate(cal.getTime());
status.setActiontime(cal.getTime());
status.setModemid("mqttreceive");
status.setRemark("offline");
status.setStatus(false);
try{
service.updateModemStatus(false, status);
}catch(Exception ex1){
}
suscribeData();
}
and from the above code i got my connections were online but i stopped receving data on subscribed topics so another method i tried that i am checking connection status from another function from database like i set the connection online when i connect and offline on connectionLost and i can call to connect(suscribeData()) but it leaves me with too many open files in tomcat within few days how can i make sure previous open files should close
like System.exit(1) on connectionLost() so that current process will close and i will reconnect after checking the status
or please suggest me if there is any other logic i can use to maintain my connections
Your catch block does nothing in method connectionLost.. it should do something like this:
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
You should also disconnect your MQTT client whenever not required..i.e processing over:
myClient.disconnect();

How to send email as a independent code for faster response?

On click of a submit button , i am calling a Jersey REST Web-service which is responsible to
1 .Insert record in the database
2.And send email .
This is my code
if (operation.equals("Insert")) {
String SQLInsertMgmtUser = "INSERT INTO User (depotID , emp_ID , appUserName)VALUES(? , ? , ?)";
String sendEmail = SendEmailUtility.sendmail(empmail, generatedPwd_str);
}
public static String sendmail(String sendemalto,String generatedpwd) throws IOException
{
String result = "fail";
Properties props_load = getProperties();
try {
// Code to send the email Using java mail API
result = "success";
} catch (MessagingException e) {
result = "fail";
logger.error("Exception Occured"+ "sendemalto" +sendemalto , e);
}
return result;
}
public static Properties getProperties()
{
if (props == null) {
File configDir = new File(System.getProperty("catalina.base"), "conf");
File configFile = new File(configDir, "email.properties");
InputStream stream = null;
try {
stream = new FileInputStream(configFile);
} catch (FileNotFoundException e) {
logger.error("exception" , e);
}
props = new Properties();
try {
props.load(stream);
} catch (IOException e) {
logger.error("exception" , e);
}
}
return props;
}
This code works fine , but the issue i am facing with this code is that the Submit Operation is nearly taking 15 seconds .
My question is that , is it possible to run the send email code as a independent thread .
Please share your views as how to approach this requirement .
Simplest way to execute a task asynchronously is by using an ExecutorService.
Something like this:
public YourClass {
private ExecutorService executorService = Executors.newFixedThreadPool(10);
public void yourMethod() {
if (operation.equals("Insert")) {
String SQLInsertMgmtUser = "INSERT INTO User (depotID , emp_ID , appUserName)VALUES(? , ? , ?)";
executorService.execute(new Runnable() {
public void run() {
SendEmailUtility.sendmail(empmail, generatedPwd_str);
}
});
}
}
I would setup a localhost MTA (like OpenSMTPD) which then relays to your real MTA ("Satellite Mode"). This gives you a local queue. If it takes a few seconds to send the message to your remote MTA, that's okay as the local MTA will handle that.
This also has the advantage of centralized configuration if you want to share the MTA among multiple applications.

Upload file using Apache FTP Client does not work

I have read a half dozen threads regarding this and I'm no where closer to a solution. No matter what I change I get ftp return code 500 "The command was not accepted and the requested action did not take place." and I'm not sure how to debug that.
This is my site and I can connect with CoreFTP and read and write, so it does not seem to be a permissions issue. I've tried two different accounts, with this code and CoreFTP. One writes to the root and another is pointed to an "image_in" folder.
imageData is a byte array with a length of 166578 and stream has the same length after the InputStream call. storeFile() always returns false with a return code of 500.
One thread implied enterLocalPassiveMode() and enterRemotePassiveMode() were the culprits, but I have tried this code both with and without those lines and still I get a 500 return code.
Any idea what I'm missing?
Greg
class ImageUploadTask extends AsyncTask <Void, Void, String>{
#Override
protected String doInBackground(Void... unsued) {
try {
boolean status = false;
try {
FTPClient mFtpClient = new FTPClient();
String ip = "my domain dot com";
String userName = "ftp79815757-0";
String pass = "my password";
mFtpClient.connect(InetAddress.getByName(ip));
mFtpClient.login(userName, pass);
int reply = mFtpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
//one thread said this would do the trick
mFtpClient.enterLocalPassiveMode();
mFtpClient.enterRemotePassiveMode();
InputStream stream = new ByteArrayInputStream(imageData);
mFtpClient.changeWorkingDirectory("/images_in");
String currdir = mFtpClient.printWorkingDirectory();
if (!mFtpClient.storeFile("remoteName.jpg", stream)) {
Log.e("FTPUpload", String.valueOf(mFtpClient.getReplyCode()));
}
stream.close();
mFtpClient.disconnect();
}
else {
Log.e("FTPConnected", String.valueOf(reply));
}
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
} catch (Exception e) {
if (dialog.isShowing())
dialog.dismiss();
Toast.makeText(getApplicationContext(),
"Error",
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
return null;
}
}
You forgot to set file type
mFtpClient.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
If it still doesn't work then you have following options:
If you insist on using Apache FTP Client then follow this example
Or you could try this example
The second example worked in my case.
You need to use: enterLocalPassiveMode
mFtpClient.enterLocalPassiveMode();
If you then do other operations, you might have to go back active with enterLocalActiveMode.

Java exceptions - try for the n'th time to return to the "try" statement block

I'm trying to make a call that might throw an exception due to server being down.
this is what i want to accomplish:
Server server = serverQueue.poll();
try {
if (server==null){return null}
server.makeConnection();
} catch (Exception e) {
// try another server
server = serverQueue.poll();
// now return to try block?
}
So i have 5 servers and maybe in later stage i'll add some more. So i want to connect to
anyone of them in this manner. How can i return to the try block? is there anything such as a statement like this below in java?:
Server server = serverQueue.poll();
outerBlock:
try {
if (server==null){return null}
server.makeConnection();
} catch (Exception e) {
// try another server
server = serverQueue.poll();
continue outerBlock;
}
Basically a loop:
Server server = serverQueue.poll();
boolean connected = false;
while (!connected) {
if (server == null) {
return null;
}
try {
server.makeConnection();
connected = true;
} catch (Exception e) {
// Presumably log something here, for management info
// try another server
server = serverQueue.poll();
}
}
Or to avoid the duplication:
Server server;
boolean connected = false;
while (!connected) {
server = serverQueue.poll();
if (server == null) {
return null;
}
try {
server.makeConnection();
connected = true;
} catch (Exception e) {
// Presumably log something here, for management info
}
}
You might consider isolating the "find a server" part of that into its own function.
You need to put your try block inside a simple loop, either while or for.
ou can use a for loop
Server server;
for(int i=0;i<=numberOFServers-1;i++){
server = serverQueue.poll();
try {
if (server==null){return null}
server.makeConnection();
} catch (Exception e) {
System.out.println("Server : " +i+ " could not establish connection");
}
}

Creating a step by step validation

I am trying to make a monitoring application for a FTP server using FTP4J(referred to as client in the code example).
It connects to a FTP, logs in, creates a file locally, uploads file, downloads file, validates the files are the same, cleans up files on ftp and locally and disconnects.
All this is already made but my question is how do I best log what has happened and break when an error is detected?
The simple solution I could think of was to make a Boolean that shows if previous steps where successful and only do next step if they where.
StringBuilder sb = new StringBuilder();
boolean noError = true;
// Connect to FTP
try {
client.connect(hostname, port);
} catch (Exception e) {
noError = false;
sb.append("failed to connect<br>");
}
//Logging in to FTP
if(noError) {
try {
client.login(username, password);
} catch (Exception e) {
noError = false;
sb.append("failed to login<br>");
}
}
...
// Close connection
if(client.isConnected()) {
try {
client.disconnect(true);
} catch (Exception e) {
sb.append("failed to disconnect<br>");
}
}
another solution I could think of was nested try/catch but that looked even worse, is there a better way of doing this?
The solution is simple: don't catch the exception. As soon as an exception is thrown and is not caught, the whole process will stop. Or catch it but transform it into your own exception with the appropriate error message, and throw this exception.
Side note: you should use a boolean and not a Boolean to store a non-nullable boolean value.
StringBuilder sb = new StringBuilder();
Boolean noError = true;
// Connect to FTP
try {
client.connect(hostname, port);
client.login(username, password);
} catch (ConnectException ce) {
sb.append("Couldn't connect: ");
sb.append(ce.getMessage);
} catch (LoginException le) {
sb.append("Couldn't login: ");
sb.append(le.getMessage);
} finally {
if(client.isConnected()) {
try {
client.disconnect(true);
} catch (Exception e) {
sb.append("failed to disconnect<br>");
}
}

Categories

Resources