Hi developers in my app i perform two operation one is to connect a specific wifi by providing SSID and password programmatically and another one is interact with MQTT. Both operation work fine individually , but when first connect to WIFI programmatically and after that if i am trying to connect MQTT it throws Exception.
MqttException (0) - java.net.SocketException: socket failed: ENONET (Machine is not on the network)
1608792187.259 31589-31589/com.asiczen.azlock W/System.err: at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
1608792187.259 31589-31589/com.asiczen.azlock W/System.err: at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:690)
1608792187.259 31589-31589/com.asiczen.azlock W/System.err: at java.lang.Thread.run(Thread.java:919)
And here is my Wifi connection.
private void connectToBrideAboveQ(String networkSSID, String networkPass){
WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder();
builder.setSsid(networkSSID);
builder.setWpa2Passphrase(networkPass);
WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();
NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
networkRequestBuilder.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
networkRequestBuilder.setNetworkSpecifier(wifiNetworkSpecifier);
NetworkRequest networkRequest = networkRequestBuilder.build();
cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
networkCallback = new ConnectivityManager.NetworkCallback(){
#Override
public void onAvailable(#NonNull Network network) {
super.onAvailable(network);
Toast.makeText(MainActivity.this, "Connected", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onAvailable: "+network);
cm.bindProcessToNetwork(network);
}
};
cm.requestNetwork(networkRequest, networkCallback);
}
And here is mqtt connection code
mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
mqttClient = new MqttAndroidClient(this, url, id);
mqttClient.setCallback(new MqttCallback() {
#Override
public void connectionLost(Throwable throwable) {
doConnectTask = true;
Log.d(TAG, "MQTT connectionLost: ");
}
#Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
}
#Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
});
mqttClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken iMqttToken) {
Log.d(TAG, "MQTT CONNECTED: ");
}
#Override
public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
doConnectTask = true;
//setNewMqttClient();
throwable.printStackTrace();
Log.d(TAG, "MQTT FAILER onFailure: ");
}
});
Thanks in advance
Finally I solve this before connecting to MQTT just call cm.bindProcessToNetwork(null); this solve my problem.
Related
I'm playing around with MQTT and Android, but I can't seem to connect the client to the broker. This is how the code looks like:
String clientId = MqttClient.generateClientId();
MqttAndroidClient client = new MqttAndroidClient(this, brokerIp, clientId);
client.setCallback(new MqttCallback() {
#Override
public void connectionLost(Throwable cause) {
Log.i(TAG, "connectionLost");
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
Log.i(TAG, "messageArrived");
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.i(TAG, "deliveryComplete");
}
});
client.connect().setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.i(TAG, "Connection success");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.i(TAG, "Connection failed: ", exception);
}
});
The problem is that none of the callbacks are ever triggered. Running mosquitto on verbose mode there are no connections coming in from this client, and checking the log I don't see any Exception raised.
I tried locally and on the cloud and it doesn't connect to any, while a client I have on the backend side can connect to both using the same host and port.
What am I missing?
Turns out the MqttService needs to be declared in the manifest to be able to bind to the Paho Android Service correctly:
<service android:name="org.eclipse.paho.android.service.MqttService"/>
I'm trying to create a simple chat using Socket IO, Android and Node.
When I run the app and try to connect to the server, it always fails with a timeout error and I can't figure out why.
Here's the Node code:
app = require('express')()
http = require('http').createServer(app)
io = require('socket.io')(http)
app.get('/', (req,res) => {
res.send('Chat server is running on port 5000')
})
/**
* Defines a listener to an event called connection and this event will be fired from the client side
*/
io.on('connection', (socket) => {
console.log('user connected')
})
http.listen(5000, () => {
console.log('Node app is running on port 5000')
})
Here's the Android code (Editted according to Marcos Casagrande Answer:
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import com.github.nkzawa.engineio.client.transports.WebSocket;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
Intent intent = getIntent();
if(intent.hasExtra(NICKNAME)){
mNickname = intent.getStringExtra(NICKNAME);
Log.d(TAG, "chatapp onCreate: " + mNickname);
}
try {
IO.Options opts = new IO.Options();
opts.transports = new String[]{WebSocket.NAME};
mSocket = IO.socket("http://10.0.0.21:5000", opts);
mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(TAG, "chatapp call: connected to server");
}
});
mSocket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(TAG, " chatapp call: disconnected from the server");
}
});
mSocket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(TAG, "chatapp call: connection error");
}
});
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(TAG, "chatapp call: connection timeout");
}
});
mSocket.connect();
} catch (Exception e) {
Log.d(TAG, "onCreate: something unexpected happened");
e.printStackTrace();
}
I try to run the app on virtual device through Android Studio I keep getting Connection timeout error. Can someone tell me, what am I doing wrong?
The connection won't happen instantly, it's asyncrhonous, attach the correct handlers and check for connection or errors in there.
mSocket = IO.socket("http://localhost:5000");
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
mSocket.connect();
// ....
private Emitter.Listener onConnect = new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(TAG, "connected...");
// This doesn't run in the UI thread, so use:
// .runOnUiThread if you want to do something in the UI
}
};
private Emitter.Listener onConnectError = new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(TAG, "Error connecting...");
}
};
I recommend using WebSocket transport in android, to avoid polling errors, you can check my answer here:
How to set transports for SocketIO in Android?
You have to use 2 AVD's instead of physical devices to connect with this IP. If now try with http://10.0.2.2:5000
I am trying to learn basic MQTT integration in Android. I am using a mosquitto broker to publish and subscribe messages. I am running the code on a real device and getting this exception :
Unable to connect to server (32103) - java.net.ConnectException:
failed to connect to /192.168.0.103 (port 1883) after
30000ms: isConnected failed: ECONNREFUSED
Here's my code:
public class HomeActivity extends AppCompatActivity{
private MqttAndroidClient client;
private final MemoryPersistence persistence = new MemoryPersistence();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(this.getApplicationContext(), "tcp://192.168.0.103:1883", "androidSampleClient", persistence);
mqttAndroidClient.setCallback(new MqttCallback() {
#Override
public void connectionLost(Throwable cause) {
System.out.println("Connection was lost!");
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
System.out.println("Message Arrived!: " + topic + ": " + new String(message.getPayload()));
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("Delivery Complete!");
}
});
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
try {
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
System.out.println("Connection Success!");
try {
System.out.println("Subscribing to /test");
mqttAndroidClient.subscribe("/test", 0);
System.out.println("Subscribed to /test");
System.out.println("Publishing message..");
mqttAndroidClient.publish("/test", new MqttMessage("Hello world testing..!".getBytes()));
} catch (MqttException ex) {
}
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
System.out.println("Connection Failure!");
System.out.println("throwable: " + exception.toString());
}
});
} catch (MqttException ex) {
System.out.println(ex.toString());
}
}
}
I've tried using different ports but the error is same. Can anyone help what am i doing wrong?
As you are getting started, you need to see see how different implementations work. Take a look at my implementation. I use a separated class for MQTT specific stuff.
MqttUtil.java
public class MqttUtil {
private static final String MQTT_TOPIC = "test/topic";
private static final String MQTT_URL = "tcp://localhost:1883";
private static boolean published;
private static MqttAndroidClient client;
private static final String TAG = MqttUtil.class.getName();
public static MqttAndroidClient getClient(Context context){
if(client == null){
String clientId = MqttClient.generateClientId();
client = new MqttAndroidClient(context, MQTT_URL, clientId);
}
if(!client.isConnected())
connect();
return client;
}
private static void connect(){
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
mqttConnectOptions.setKeepAliveInterval(30);
try{
client.connect(mqttConnectOptions, null, new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d(TAG, "onSuccess");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.d(TAG, "onFailure. Exception when connecting: " + exception);
}
});
}catch (Exception e) {
Log.e(TAG, "Error while connecting to Mqtt broker : " + e);
e.printStackTrace();
}
}
public static void publishMessage(final String payload){
published = false;
try {
byte[] encodedpayload = payload.getBytes();
MqttMessage message = new MqttMessage(encodedpayload);
client.publish(MQTT_TOPIC, message);
published = true;
Log.i(TAG, "message successfully published : " + payload);
} catch (Exception e) {
Log.e(TAG, "Error when publishing message : " + e);
e.printStackTrace();
}
}
public static void close(){
if(client != null) {
client.unregisterResources();
client.close();
}
}
}
And you can simply use it in your HomeActivity. Check it below:
public class HomeActivity extends AppCompatActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get Mqtt client singleton instance
MqttUtil.getClient(this);
// Publish a sample message
MqttUtil.publishMessage("Hello Android MQTT");
}
}
For testing purposes, use your Mosquitto sub client and see if you get the message.
Hope that helps!
try using port 8883
String clientId = MqttClient.generateClientId();
final MqttAndroidClient client =
new MqttAndroidClient(this.getApplicationContext(), "ssl://iot.eclipse.org:8883",
clientId);
try {
MqttConnectOptions options = new MqttConnectOptions();
InputStream input =
this.getApplicationContext().getAssets().open("iot.eclipse.org.bks");
options.setSocketFactory(client.getSSLSocketFactory(input, "eclipse-password"));
IMqttToken token = client.connect(options);
token.setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
// We are connected
Log.d(TAG, "onSuccess");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
// Something went wrong e.g. connection timeout or firewall problems
Log.d(TAG, "onFailure");
}
});
} catch (MqttException | IOException e) {
e.printStackTrace();
}
I am trying to develop a chat application but instead of Google message service I tried writing xmmp node server.
I am able to login in to server.But getting message saying feature not implemented.
<iq to='359648069251166#10.10.25.126/Smack' id='cu03M-5' type='error'><error type='cancel'><feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>
android code
final TelephonyManager mngr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.setServiceName(IPADRESS)
.setHost(IPADRESS)
.setPort(5222)
.build();
AbstractXMPPConnection conn2 = new XMPPTCPConnection(config);
conn2.setPacketReplyTimeout(1000);
SmackConfiguration.DEBUG = true;
conn2.connect();
conn2.addConnectionListener(new ConnectionListener() {
#Override
public void connected(XMPPConnection connection) {
}
#Override
public void authenticated(XMPPConnection connection, boolean resumed) {
}
#Override
public void connectionClosed() {
}
#Override
public void connectionClosedOnError(Exception e) {
}
#Override
public void reconnectionSuccessful() {
}
#Override
public void reconnectingIn(int seconds) {
}
#Override
public void reconnectionFailed(Exception e) {
}
});
conn2.addAsyncPacketListener(new PacketListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
if (packet != null) {
Log.d("stanza", "received" + packet.toXML());
Toast.makeText(getApplicationContext(), packet.toXML(), Toast.LENGTH_LONG).show();
}
}
}, new PacketFilter() {
#Override
public boolean accept(Stanza packet) {
return true;
}
});
Roster roster = Roster.getInstanceFor(conn2);
//Get all rosters
Collection<RosterEntry> entries = roster.getEntries();
//loop through
for (RosterEntry entry : entries) {
//example: get presence, type, mode, status
Presence entryPresence = roster.getPresence(entry.getUser());
Presence.Type userType = entryPresence.getType();
Presence.Mode mode = entryPresence.getMode();
String status = entryPresence.getStatus();
Log.d("stanza",userType+" "+status);
}
roster.addRosterListener(new RosterListener() {
#Override
public void presenceChanged(Presence presence) {
//Called when the presence of a roster entry is changed
}
#Override
public void entriesUpdated(Collection<String> arg0) {
// Called when a roster entries are updated.
}
#Override
public void entriesDeleted(Collection<String> arg0) {
// Called when a roster entries are removed.
}
#Override
public void entriesAdded(Collection<String> arg0) {
// Called when a roster entries are added.
}
});
conn2.login(mngr.getDeviceId(), "secret");
Presence presence = new Presence(Presence.Type.available);
presence.setStatus("I’m available");
conn2.sendPacket(presence);
ChatManager chatManager = ChatManager.getInstanceFor(conn2);
Chat chat = chatManager.createChat(mngr.getDeviceId(), new ChatMessageListener() {
#Override
public void processMessage(final org.jivesoftware.smack.chat.Chat chat,
final Message message) {
Log.i("MyXMPP_MESSAGE_LISTENER", "Xmpp message received: '"
+ message);
if (message.getType() == Message.Type.chat
&& message.getBody() != null) {
Log.d("stanza", message.toString());
// processMessage(chatMessage);
}
}
});
// Add a packet listener to get messages sent to us
Message message = new Message();
message.setFrom(mngr.getDeviceId());
message.setTo(mngr.getDeviceId());
message.setType(Message.Type.chat);
message.setSubject("jhelloworld");
chat.sendMessage(message);
}catch (Exception e){
Log.d("error",e.getMessage());
}
I took server from here.
server side code.
var startServer = function (done) {
// Sets up the server.
server = new xmpp.C2S.TCPServer({
port: 5222,
domain: 'localhost'
})
server.on('connection', function (client) {
// That's the way you add mods to a given server.
// Allows the developer to register the jid against anything they want
client.on('register', function (opts, cb) {
console.log('REGISTER')
cb(true)
})
// Allows the developer to authenticate users against anything they want.
client.on('authenticate', function (opts, cb) {
console.log('server:', opts.username, opts.password, 'AUTHENTICATING')
if (opts.password === 'secret') {
console.log('server:', opts.username, 'AUTH OK')
cb(null, opts)
} else {
console.log('server:', opts.username, 'AUTH FAIL')
cb(false)
}
})
client.on('online', function () {
console.log('server:', client.jid.local, 'ONLINE')
client.send("")
})
// Stanza handling
client.on('stanza', function (stanza) {
console.log('server:', client.jid.local, 'stanza', stanza.toString())
var from = stanza.attrs.from
stanza.attrs.from = stanza.attrs.to
stanza.attrs.to = from
client.send(stanza)
})
// Stanza handling
client.on('chat', function (stanza) {
console.log('server:', client.jid.local, 'chat', stanza.toString())
client.send(stanza)
});
// On Disconnect event. When a client disconnects
client.on('disconnect', function () {
console.log('server:', client.jid.local, 'DISCONNECT')
})
})
server.on('listening', done)
}
startServer(function (){
console.log("server localhost started at 5222 localport");
});
I tried many solution from stackoverflow and smack community but didnt.
help will be appreciated.
I have developed an iPhone application with socket.io, it is working fine with HTTP and HTTPS.
I have developed Android application with socket.io. I was using HTTP it was working fine. Now I am trying to use HTTPS. I made some changes, but it is not at all connecting with server. Always I am getting websocket error.
I downloaded the library from https://github.com/socketio/ for iPhone and Android
Below is my sample code
try {
HostnameVerifier verifier = new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
// Not doing any validation for testing
Log.i(TAG, "Verifying host name ::: " + hostname);
return true;
}
};
IO.setDefaultSSLContext(SSLContext.getDefault());
IO.setDefaultHostnameVerifier(verifier);
IO.Options opts = new IO.Options();
opts.reconnection = false;
opts.secure = true;
opts.transports = new String [] {WebSocket.NAME};
socket = IO.socket("https://website.com:6001", opts);
Log.i(TAG, "Initialized socket io");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.i(TAG, "We are connected to server");
}
});
socket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.i(TAG, "We are disconnected from server");
socket.off();
}
});
socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.i(TAG, "Connection Error");
for (Object obj : args) {
Log.e(TAG, "Errors :: " + obj);
}
}
});
socket.on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.i(TAG, "Connection Timeout Error");
}
});
socket.on("res", new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.i(TAG, "got response from server");
}
});
socket.connect();
} catch (Exception e) {
Log.e(TAG, "Error :: " + e);
}
Any idea ?