In the offline capabilities section for Web, it is described here how to detect if the client is connected to the internet or not. However, Firebase doesn't seem to call the event handler every time a client connects or disconnects when running in Node environment. It works as expected when running in the browser i.e. it calls the event handler every time the client is connected or disconnected from the internet.
Check out this jsFiddle. Once you run the fiddle and you connect or disconnect from the internet, you will see a corresponding 'connected' or 'disconnected' message in the console.
I ran the below code in Node which is exactly same as the code I ran in browser. While running in Node environment, I observed that I received the initial 'connected' and 'disconnected' message but if I connected and disconnected from the internet again, no messages are printed meaning that the event handler is not called
var Firebase = require('firebase');
var ref = new Firebase("<FIREBASE-APP>");
var connectedRef = ref.child(".info/connected");
connectedRef.on("value", function(snap) {
if (snap.val() === true) {
console.log("connected");
} else {
console.log("not connected");
}
});
I just ran the same script in node on my system:
$ node connected.js
not connected
connected
not connected
connected
The first two come from the initial start of the script. The last two log lines came after I turned the wifi of my laptop off for a minute and then on again.
It may take some time before the Firebase client detects that it lost the connection to its servers, so be patient. The reason for the time it takes depends on the environment (browser/node) you run in, since the Firebase client depends on that environment to provide the WebSocket and detect time-outs.
Related
Is there a way in dart to get notified (listen to) when the network disconnecting and do action only if it off?.
I do not want to check internet connection so no need for pinging google.com (connection to router without internet is still good).
Searching for simple way that interact with the network interfaces of the device and listen to change or return True/False about the network state.
In worse case I can use Process.run(...) with bash commend but this ugly fix.
No flutter here only pure dart (dart Console Application).
If you are running the program on linux you can use bash commend like this
// Check if connected to network, if there is a connection than return network name
Future<String> getConnectedNetworkName() async {
return await Process.run('iwgetid',
['-r']).then((ProcessResult results) {
print(results.stdout.toString());
return results.stdout.toString().replaceAll('\n', '');
});
}
This will return network name even if the network does not connected to the internet
I have developed simple chat system using signal R.
In case when internet is disconnect and reconnect after 2 minutes all signal r server methods are invoking but client methods are not getting response.
Can some one tell me what can I do for that?
If the internet disconnects so does the signalR client. You will need to handle reconnecting. The below code is the example from the site below to show you how to handle signalR continuously trying to reconnect in case a disconnect happens.
$.connection.hub.disconnected(function() {
setTimeout(function() {
$.connection.hub.start();
}, 5000); // Restart connection after 5 seconds.
});
More information can be found here: http://www.asp.net/signalr/overview/guide-to-the-api/handling-connection-lifetime-events
I have two meteor applications connected via DDP on different servers and server A send data to server B. This is the way they work.
Server A
Items = new Meteor.Collection('items');
Items.insert({name: 'item 1'});
if (Meteor.isServer) {
Meteor.publish('items', function() {
return Items.find();
});
}
Server B
var remote = DDP.connect('http://server-a/');
Items = new Meteor.Collection('items', remote);
remote.subscribe('items');
Items.find().observe({
added: function(item) {
console.log(item);
}
});
Every time I call Items.insert(something) on server A, on Server B I got a log on the console with the object I saved on Server A. But if Server B lost Internet connection, the data inserted on Server A doesn't appear anymore on Server B when it reconnect to Internet.
Server B is connected to Internet through a router. This problem only happen when I disconnect and reconnect the router, not when I disconnect and reconnect the server from the router. Both servers are on different networks and connect via Internet.
I created a timer on Server B that call remote.status() but always get { status: 'connected', connected: true, retryCount: 0 } when connected or disconnected from Internet.
Update: steps to reproduce
I created a project on github with the testing code https://github.com/camilosw/ddp-servers-test. Server A is installed on http://ddpserverstest-9592.onmodulus.net/
My computer is connected to Internet through a wireless cable modem.
Run mrt on server-b folder
Go to http://ddpserverstest-9592.onmodulus.net/ and click the link Insert (you can click delete to remove all previous inserts). You must see a message on your local console with the added item.
Turn off the wireless on the computer and click the insert link again. (You will need to click on another computer with Internet access, I used an smartphone to click the link)
Turn on the wireless on the computer. You must see a message on your local console with the second item.
Now, turn off the cable modem and click the insert link again.
Turn on the cable modem. This time, the new item doesn't appear on the console.
I also did it with an android smartphone using the option to share Internet to my computer via wireless. First I turned off and on the wireless on my computer and worked right. Then I turned off and on the Internet connection on the smartphone and I got the same problem.
Update 2
I have two wireless router on my office. I found that the same problem happen if I move between routers.
Emily Stark, from the Meteor Team, confirmed that this is due to a missing feature on the current implementation (version 0.7.0.1 at the moment I write this answer). Their answer is here https://github.com/meteor/meteor/issues/1543. Below is their answer and a workaround she suggest:
The server-to-server connection is not reconnecting because Meteor currently doesn't do any heartbeating on server-to-server DDP connections. Just as in any other TCP connection, once you switch to a different router, no data can be sent or received on the connection, but the client will not notice unless it attempts to send some data and times out. This differs from browser-to-server DDP connections, which run over SockJS. SockJS does its own heartbeating that we can use to detect dead connections.
To see this in action, here is some code that I added to server-b in your example:
var heartbeatOutstanding = false;
Meteor.setInterval(function () {
if (! heartbeatOutstanding) {
console.log("Sending heartbeat");
remote.call("heartbeat", function () {
console.log("Heartbeat returned");
heartbeatOutstanding = false;
});
heartbeatOutstanding = true;
}
}, 3000);
remote.onReconnect = function () {
console.log("RECONNECTING REMOTE");
};
With this code added in there, server-b will reconnect after a long enough time goes by without an ACK from server-a for the TCP segments that are delivering the heartbeat method call. On my machine, this is just a couple minutes, and I get an ETIMEDOUT followed by a reconnect.
I've opened a separate task for us to think about implementing heartbeating on server-to-server DDP connections during our next bug week. In the meantime, you can always implement heartbeating in your application to ensure that a DDP reconnection happens if the client can no longer talk to the server.
I think you are not passing DDP connection object to the Collection correctly, try:
var remote = DDP.connect('http://server-a/');
Items = new Meteor.Collection('items', { connection: remote });
It might be useful for debugging to try all these connection games from the browser console first, since Meteor provides the same API of connection/collections on the client (except for the control flow). Just open any Meteor application and try this lines from the console.
I revised a sample of communication between two ddp server, based on camilosw's code.
Server A as Cloud Data Center. Server B as Data Source, if some data changed, should be send to Server A.
You can find the code from https://github.com/iascchen/ddp-servers-test
I'm using Chrome's Serial Port API (http://developer.chrome.com/apps/serial.html) in a Web App.
The problem I have is that pretty much all serial ports now are implemented via USB devices. If the user disconnects (or just resets) the USB device, I don't have any way of knowing. Not only that, because the app hasn't disconnected in Chrome (because it didn't know), if the USB device is plugged back in, bad things happen (on Linux it just gets a different name, but in Windows it is not usable at all).
The best I can manage is:
var checkConnection = function() {
chrome.serial.getControlSignals(connectionInfo.connectionId, function (sigs) {
var connected = "cts" in sigs;
if (!connected) console.log("Disconnected");
});
} // called every second or so
Is there a better way? a callback would be ideal!
It looks it should be safe on all platforms to assume that getting a read callback with 0 bytes means EOF, which in turn is a good indication that the device has been disconnected.
chrome.serial.read(connectionId, function(readInfo) {
if (readInfo.bytesRead === 0) {
/// Safely assume the device is gone. Clean up.
chrome.serial.close(connectionId);
/// ...
}
});
The serial API will be improving over the next few weeks (in Canary at least) to add stability improvements, an event-based read API, and the ability to more clearly detect timeouts and error conditions (like a disconnected device). You can track that progress at http://crbug.com/307184.
I have an API which uses netty to open client connection to a tcp server. The server may send data to the client at any time. I'm facing the following scenario:
Client connects to server
Sends data to server
Disconnects and the JVM exist (not sure happens first)
This is what I expect:
Client connects to server
Sends data to server
Client simply keeps the connections open, waiting to receive data or for the user of client API to send data.
This is an outline of my connection method (obviously there is a much larger API around it):
```
public FIXClient connect(String host, int port) throws Throwable {
...
ChannelPipeline pipe = org.jboss.netty.channel.Channels.pipeline(...);
ChannelFactory factory = new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
ClientBootstrap bootstrap = new ClientBootstrap(factory);
bootstrap.setPipeline(pipe);
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("keepAlive", true);
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
//forcing the connect call to block
//don't want clients to deal with async connect calls
future.awaitUninterruptibly();
if(future.isSuccess()){
this.channel = future.getChannel();
//channel.getCloseFuture();//TODO notifies whenever channel closes
}
else{
throw future.getCause();//wrap this in a more specific exception
}
return this;
}
```
That has nothing todo with netty... You need to make sure your "main" method will not exist if you call it from there. Otherwise it the job of the container..
There's a couple of ways you can do this, but one thing I have observed, is that with this code:
ChannelFactory factory = new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
... if you make a successful connection, your JVM will not shutdown of it's own accord for some time until you force it (like a kill) or you call a releaseExternalResources() on your channel factory. This is because:
The threads created by Executors.newCachedThreadPool() are nonDaemon threads.
At least 1 thread would be created once you submit your connection request.
The cached thread pool threads have a keep alive time of 60 seconds, meaning they don't go away until they've been idle for 60 seconds, so that would be 60 seconds after your connect and send (assuming that they both completed).
So I'm not sure if you're diagnosing the issue correctly. Having said that, I recommend you handle the task this this way:
Once you boot in your main method (in the main thread)
Now launch all your actual useful work in new threads.
Once the useful threads have been launched, in the main thread, call Thread.currentThread().join(). Since main is always non-dameon, you have made sure the JVM will not shutdown until you're good and ready.
At some point, unless you want to kill -9 the JVM as a shutdown strategy, you will want a controlled shutdown, so you can add a shutdown hook to shutdown Netty and then interrupt the main thread.
I hope that's helpful.