I connect to the node server with socketio.SocketIO running as a service.And, When Service restarts,opens socket.io without socket.io closure.That's a problem.
A device making multiple socketIO connection on the server side.So the server is swelling..
! I am using gottox/socketio-java-client on android.
Check Socket is connected or not using socket.isConnected().
This will return true if socket is connected
Its just an idea so i don't know the limitations. pls let me know.
You can ping the server to check if the connection is alive.
In android
socket.emit("ping","ping");
socket.on("pong",pingHandler); //EmitterListener
private Emitter.Listener pingHandler=new Emitter.Listener(){
#Override
public void call(final Object... args) {
Log.d("SocketStatus","Connection is active");
});
}
and make the server return response for the ping
socket.on("ping",function(data){
socket.emit("pong","pong"); //from your server ex.Node.js
});
You can check the socket.connected property:
var socket = io.connect();
console.log('Connected status before onConnect', socket.socket.connected);
socket.on('connect', function() {
console.log('Connected status onConnect', socket.socket.connected);
});
It's updated dynamically, if the connection is lost it'll be set to false until the client picks up the connection again. So easy to check for with setInterval or something like that.
Another solution would be to catch disconnect events and track the status yourself.
The following is an expansion/modification of Rafique Mohammed answer above. The correct way is to try to reconnect on client side.
Internet drops (server cannot communicate disconnection to client). Server crashes (server may/may not be able to tell client. Server Restart (server can tell but that just extra work). After reconnection you will also like to rejoin the room for seamless communication
public void connectAfterDisconnectSocket(String senderActivity) {
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
boolean isConnected = false;
isConnected = mSocket != null && mSocket.connected();
if (!isConnected) {
SocketIOClient socketIOClient = new SocketIOClient();
socketIOClient.connectToSocketIO();
if (senderActivity.equals("A")) {
A.joinChatRoom(room);
}
if (senderActivity.equals("B")) {
B.joinChatRoom(room);
}
}
}
}, 0, 1000); //put here time 1000 milliseconds=1 second
}
Related
I have trouble with connecting to a local web interface (192.168.10.13:3671) that are connected to my KNX network from the emulator/phone in Android Studio.
I've tried to connect to the same web interface with a already developed app called KNXwizard and that works, but I see in the code that that app uses AsyncTask.
Always getting this error: Error creating KNXnet/IP tunneling link: tuwien.auto.calimero.KNXException: connecting from /192.168.163.198:3671 to /192.168.10.13:3671: socket failed: EPERM (Operation not permitted)
I've checked this posts
Socket failed 1
Socket failed 2
Tried everything there, added permissions to my AndroidManifest.xml, uninstalled, used physical phone etc. But nothing works.
It could be my code, I've tried searching for an alternative method for AsyncTask. So it could be that the code is written wrong. Hope someone could help me out.
MainActivity:
public class MainActivity extends AppCompatActivity {
private static InetSocketAddress local = new InetSocketAddress("192.168.163.198", 3671);
private static InetSocketAddress server = new InetSocketAddress("192.168.10.13",
KNXnetIPConnection.DEFAULT_PORT);
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.button);
ExecutorService executorService = Executors.newSingleThreadExecutor();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
executorService.execute(new Runnable() {
#Override
public void run() {
//doInBackground
System.out.println("This example establishes a tunneling connection to the KNXnet/IP server " + server);
// A KNX tunneling link supports NAT (Network Address Translation) if required.
// We also indicate that the KNX installation uses twisted-pair (TP) medium, with TP1 being the most common.
// KNXNetworkLink is the base interface implemented by all supported Calimero links to a KNX network.
try (KNXNetworkLink knxLink = KNXNetworkLinkIP.newTunnelingLink(local, server, false, TPSettings.TP1)) {
System.out.println("Connection established to server " + knxLink.getName());
System.out.println("Close connection again");
} catch (KNXException | InterruptedException e) {
// KNXException: all Calimero-specific checked exceptions are subtypes of KNXException
// InterruptedException: longer tasks that might block are interruptible, e.g., connection procedures. In
// such case, an instance of InterruptedException is thrown.
// If a task got interrupted, Calimero will clean up its internal state and resources accordingly.
// Any deviation of such behavior, e.g., where not feasible, is documented in the Calimero API.
System.out.println("Error creating KNXnet/IP tunneling link: " + e);
}
}
});
}
});
}
I figured it out.
It was a stupid mistake with the IP address, should have seen that before. I just change the IP address to that I have on the phone I was connected to (192.168.10.15).
I set up a very basic node.js server with the following code:
const express = require("express");
const app = express();
const port = 8000;
const ip = '192.16x.xxx.yyy'; // the x's and y's are placeholders. I didnt want to write my real IP here
const http = require("http").createServer();
const io = require("socket.io")(http);
// using the socket, we can send/receive data to/from the client
// the server listens for the "connection" event
io.on("connection", (socket) => {
// emit an event called "welcome" with a string as data to the client using its socket
// so, whenever the client connects to the server, it receives this welcome message
socket.emit("welcome", "Hello and Welcome to the Socket.io server.");
console.log("a new client is connected.")
});
// the server listens on the specified port for incoming events
http.listen(port, ip, () => {
console.log("Server is listening on " + ip + ":" + port);
});
So, the server is listening for the "connection" event and sends a welcome message when a client connects to the server.
The client which is an Android app looks like this:
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import com.github.nkzawa.emitter.Emitter;
import java.net.URISyntaxException;
public class MainActivity extends AppCompatActivity {
private Socket mSocket;
private TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.textView);
try {
/*
* IO.socket() returns a socket for the specified URL and port with the
* default options. Notice that the method caches the result, so you can
* always get a same Socket instance for an url from any Activity or
* Fragment.
* */
mSocket = IO.socket("http://192.16x.xxx.yyy:8000");
} catch (URISyntaxException e) {
e.getMessage();
}
/*
* We then can make the socket listen an event on onCreate lifecycle callback.
* */
mSocket.on("welcome", onNewMessage);
/*
* And we explicitly call "connect()" to establish the connection here.
* In this app, we use onCreate lifecycle callback for that, but it
* actually depends on your application.
* */
mSocket.connect();
}
private Emitter.Listener onNewMessage = new Emitter.Listener() {
#Override
public void call(final Object... args) {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
String message = (String) args[0];
mTextView.setText("Received from Server: " + message);
}
});
}
};
/*
* Since an Android Activity has its own lifecycle, we should carefully manage the
* state of the socket also to avoid problems like memory leaks. In this app, we’ll
* close the socket connection and remove all listeners on onDestroy callback of
* Activity.
* */
#Override
protected void onDestroy() {
// socket gets disconnected
mSocket.disconnect();
// off() removes the listener of the "welcome" event
mSocket.off("welcome", onNewMessage);
super.onDestroy();
}
}
The client code is also very simple: It connects to the server and displays the message it gets from the server.
I got this ex. from the official Socket.IO website at https://socket.io/blog/native-socket-io-and-android/.
When I start the server with node server.js on the terminal of my laptop and use an Android emulator, then everything works fine.
But when I connect my real Android device to my laptop using a USB then the connection does not take place.
Why Android app (running within the real device) does not connect to the server ?
This worked for me: I created a socket with the IP 0.0.0.0, You should Change your IP at your node.js to this value.
Than i opened cmd and entered ipconfig to see what my ip adress is, this is your local IP adress. In the Code i am connecting to this IP Adress.
For example if you see IP 192.168.178.50 in your ipconfig you Change your Android Code to
mSocket = IO.socket("http://192.168.178.50:8000");
And your Node.js Code should look like
const ip = '0.0.0.0';
And dont Forget to Restart your Server when you changed the node.js code
I am creating an Android application which uses Linphone to enable Voip calls.
When the connection is lost, I'm attempting to reconnect to the Sip server like this:
#Override
public void reregister()
{
handler.post(new Runnable()
{
#Override
public void run()
{
linphoneCore.getDefaultProxyConfig().edit();
linphoneCore.getDefaultProxyConfig().enableRegister(true);
linphoneCore.getDefaultProxyConfig().done();
}
});
}
The problem is that many times when using it, the onRegisterFailed, onRegisterSucceeded and even onRegisterProcessing are not getting called, even though the internet connection is fine.
Is the way I'm trying to reregister correct?
to attempt a reconnection with the same register informations, you can used:
linphone_core_refresh_registers()
So in your case in Java:
linphoneCore.refreshRegisters()
I an trying to stop peer discovery in wifi direct using the code below.
public void StopPeerDiscovery(){
manager.stopPeerDiscovery(channel, new ActionListener() {
#Override
public void onSuccess() {
Log.d(WiFiDirectActivity.TAG,"Stopped Peer discovery");
}
#Override
public void onFailure(int i) {
Log.d(WiFiDirectActivity.TAG,"Not Stopped Peer discovery");
}
});
}
I am able to see Success message (Stopped peer discovery) in logs. But other devices are still able to view it in in peer discovery..
Am I doing something wrong here? Please advise.
Thanks
This is not an issue. Actually you interpreted this onSuccess wrong. This onSuccess does not tell you that peer discovery has stopped but rather it means that your request has been successfully sent to the hardware/framework responsible for the above call, it will stop discovery asynchronously and let you know (as explained ahead). Similarly, its failure just tells that your call did not reach successfully to the framework.
You need to register a BroadcastReceiver for WIFI_P2P_DISCOVERY_CHANGED_ACTION intent. As you can read in the documentation, the extra namely EXTRA_DISCOVERY_STATE lets you know whether the discovery of peer discovery stopped.
if (WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION.equals(intent.getAction()))
{
int state = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, 10000);
if (state == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED)
{
// Wifi P2P discovery started.
}
else
{
// Wifi P2P discovery stopped.
// Do what you want to do when discovery stopped
}
}
Suppose phone finds open wi-fi network and connects to it. But wi-fi network is "inactive", i.e. when you open browser you see prompt for credentials. I have many apps on my phone(for example web-browser), which fail to work in such cases.
I want to send data using mobile network, but system still tries to use wi-fi.
NetworkInfo.isAvailable() and NetworkInfo.isConnected() still return true for the described wi-fi networks.
Any solution?
I've been having the same problem, and what I found is there is no such possibility via the Android SDK, you have to write your own way to do it.
It depends what do you want to do with the network and what do you mean by 'inactive' - you can be connected to a router, which doesn't have connection to the Internet, and there is no Android method to check such situation. As MrMichael wrote, ping is one way to check it, but in that case positive test gives you just info about ping - the network can have some heavy firewall which allows you to send pings, but i. e. will not let HTTP request through.
In that case, you have to write your own custom test for your own needs, alas - that's what I did. I just implemented simple ping-like protocol (I try to connect my socket on proper IP/port and send short message waiting for short answer). Only that gives me 100% warranty that the connection I want can be established.
As far as I am aware there is no way to force the use of a data connection over wifi (perhaps something that you shouldn't do without user interaction anyway).
I have the same requirements in many of my applications, I want to know if they have a viable network connection whilst the splash screen is loading (for example I show a read only version of the app if not).
The way that I get around this is to fire a simple service call to my server called isAlive which just returns a true imedialtly. This not only tells me that I am able to see my service, it also confirms that my server is on-line (no issues at my end). In the case that I do not get a response back in a timely fashion I inform the user that they have no network connection and "Please ensure you have a valid data/wifi connection before continuing". I then take the isConnected property for the wifi and modify this message to say "Your current Wireless connection does not internet access" or something similar.
Not quite the answer you were hoping for but maybe a possibility?
Just a suggestion: You may try using requestRouteToHost(). But first search SO for problems in using this method.
Also you'll need the CHANGE_NETWORK_STATE permission.
Try this....
I needed to do some custom work..but got it up and running...
My code switches from Wifi to Mobile network when its off.
And I am using the TimeService at port 37 to know that the Internet is DEAD while the wifi connection is still ON
//////////////////////////Edited//////////////////////////////////
Now i am putting here a complete working code i made. Please pardon me as the DRY (Don't Repeat Yourself Principle ) has been abused here. So please refactor the code and convert the duplicate codes into method , ie into a single sensible place, when using in production network
/////---------------------------Intial Available Network Checking
private boolean checkConnection(){
boolean connected = false;
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if ((ni.getTypeName().equalsIgnoreCase("WIFI")
|| ni.getTypeName().equalsIgnoreCase("MOBILE"))
& ni.isConnected() & ni.isAvailable()) {
connected = true;
}
}
}
return connected;
}
/////---------------------------Intial Available Network Checking
/////-------------------------------Check for the working Internet Connection
public boolean inetAddr(){
boolean x1 = false;
try {
Socket s = new Socket("utcnist.colorado.edu", 37);
InputStream i = s.getInputStream();
Scanner scan = new Scanner(i);
while(scan.hasNextLine()){
System.out.println(scan.nextLine());
x1 = true;
}
} catch (Exception e) {
x1 = false;
}
return x1;
}
/////-------------------------------Check for the working Internet Connection
////-------------------------------Check Mobile Conectivity Again
public boolean mobileConnect(){
boolean conn = false;
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNet = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if(activeNet != null){
conn = true;
}else{
conn = false;
}
return conn;
}
////------------------------------Check Mobile Conectivity Again
Here i am using the Above Methods....
try{
if (!checkConnection()){
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(YumZingSplashActivity.this);
myAlertDialog.setTitle("--- Connectivity Check ---");
myAlertDialog.setMessage("No Internet Connectivity");
myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YumZingSplashActivity.this.finish();
//splashHandler.removeCallbacks(launcherRunnable);
}});
System.out.println("No Internet Connectivity");
myAlertDialog.show();
}
else{
if(inetAddr()){
aphandle = APIHandling.getInstance();
aphandle.xmlCreateSession();
System.out.println("Net Connectivity is Present");
DURATION = Integer.valueOf(getString(R.string.splash_duration));
splashHandler = new Handler();
// ================ Main Code of the Application
launcherRunnable = new Runnable() {
public void run() {
Intent i = new Intent(YumZingSplashActivity.this, YumZingTabHostActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
YumZingSplashActivity.this.finish();
}
};
if (DEBUG)
{
splashHandler.post(launcherRunnable);
}
else{
splashHandler.postDelayed(launcherRunnable, DURATION);
}
}
else{
if(mobileConnect()){
if(inetAddr()){
aphandle = APIHandling.getInstance();
aphandle.xmlCreateSession();
System.out.println("Net Connectivity is Present");
DURATION = Integer.valueOf(getString(R.string.splash_duration));
splashHandler = new Handler();
// ================ Main Code of the Application
launcherRunnable = new Runnable() {
public void run() {
Intent i = new Intent(YumZingSplashActivity.this, YumZingTabHostActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
YumZingSplashActivity.this.finish();
}
};
if (DEBUG)
{
splashHandler.post(launcherRunnable);
}
else{
splashHandler.postDelayed(launcherRunnable, DURATION);
}
}else{
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(YumZingSplashActivity.this);
myAlertDialog.setTitle("--- Connectivity Check ---");
myAlertDialog.setMessage("No Internet Connectivity");
myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YumZingSplashActivity.this.finish();
//splashHandler.removeCallbacks(launcherRunnable);
}});
System.out.println("No Internet Connectivity");
myAlertDialog.show();
}
}else{
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(YumZingSplashActivity.this);
myAlertDialog.setTitle("--- Connectivity Check ---");
myAlertDialog.setMessage("No Internet Connectivity");
myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YumZingSplashActivity.this.finish();
//splashHandler.removeCallbacks(launcherRunnable);
}});
System.out.println("No Internet Connectivity");
myAlertDialog.show();
}
}
}
//setContentView(R.layout.yumzing_splash_layout);
} catch(Exception ex){
System.out.println("Leak ko catch");
}
}
You could connect to the wifi network, try connect to any page in background and verify if there is any redirection. If so, it is very likely to be the credential pages. In fact when I was trying to find how to implement the solution I have just described, I found it to be described in HttpURLConnection class documentation at Android developers site. There you can read:
Handling Network Sign-On
Some Wi-Fi networks block Internet access until the user clicks through a sign-on page. Such sign-on pages are typically presented by using HTTP redirects. You can use getURL() to test if your connection has been unexpectedly redirected. This check is not valid until after the response headers have been received, which you can trigger by calling getHeaderFields() or getInputStream(). For example, to check that a response was not redirected to an unexpected host:
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
if (!url.getHost().equals(urlConnection.getURL().getHost())) {
// we were redirected! Kick the user out to the browser to sign on?
...
} finally {
urlConnection.disconnect();
}
}
Try
InetAddress.getByName(host).isReachable(timeOut)