I have a node.js server and I am using socket.io for realtime communication between the server and clients. I have observed that if a mobile client (Using Ionic Framework) disconnects suddenly, without letting the server know about it, the sockets are alive for hours (or forever). I have read and looked on their documentation and they have options like
pingInterval, pingtimeout, heartbeat interval, heartbeat timeout, close timeout.
How do I configure these values on my server?
Which of these values have been deprecated?
Here is my code.
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
io.set('heartbeat interval', 5000);
io.set('heartbeat timeout', 8000);
io.set('timeout', 5000);
io.on('connection', function(socket){...}
None of these seem to work. Any help or guidance is highly appreciated.
PS: I am splicing sockets of my collection when a client disconnects
and it works just fine when clients tell server that they want to
disconnect gracefully.
You have to use pingTimeout as mentioned here:
https://github.com/Automattic/socket.io/issues/1900
Also make sure to set your options like the following, since io.set is gone.
var io = require('socket.io')({
pingTimeout: 5000
})
More at: http://socket.io/docs/migrating-from-0-9/#configuration-differences
However, if this doesn't work, chances are ionic is actually keeping the connection in the background. From a project around a year ago, I remember having multiple issues like this and ended up making ionic disconnect socket forcefully when it went in the background.
Related
Angular has two ways data binding which is cool, so I just wonder if it could be sync in Server-Client binding? For example, usually we would request data by $http
$http.get(apiURL)
.then(function(rsp){
console.log('getRsp', rsp);
});
I hope it could send request automatically once server side (inside database for example) changes.
In tranditionally, we can use timeout, but it is kind old way, and watsting resource. What if we can listen the server change? But how?!
You can achiece this by using socket.io. Both on server and client side. By using timeout all of the clients will repeatedly keep on calling the server even if there is no update. With sockets you can keep a channel open between server and client. The server will only notify the client whenever there is a change in the data.
You can find a lot tutorials for sockets on the internet.
I need to create a TCP connection in AppEngine (on the server side) and keep it alive indefinitely (or at least ~30 minutes). I've created a background thread, opened a java.net.Socket and attempted to read a line with a wrapped BufferedReader. After about 3 seconds of inactivity, I get the following exception:
java.net.SocketException: Socket operation timed out: The API call remote_socket.Receive() took too long to respond and was cancelled.
I'll include a skeleton of the code I'm using below. Any help would be greatly appreciated (including workarounds or information on the limitations of sockets in GAE). Thanks!
ThreadFactory tm = ThreadManager.backgroundThreadFactory();
thread = tm.newThread(new Runnable() {
#Override
public void run() {
Socket socket = null;
try {
socket = new Socket("localhost", 8000);
socket.setSoTimeout(0);
socket.setKeepAlive(true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String in = reader.readLine();
// execution never gets past here
//...
} catch (IOException e) {
e.printStackTrace();
} finally {
// ... <close socket>
}
}
});
thread.start();
In case it's relevant, here's the use case: I've got a TCP server that used to work with an embedded Applet on the client side. I'd like to redesign the Applet as a webapp, but the server still works fine, so I'd rather not change it. I'd like to write a simple servlet that keeps the TCP connection alive and feeds messages back and forth between the TCP server and the GWT client.
Sockets have lots of restrictions in GAE due to security reasons, though GAE provides many ready to use services which requires use of sockets like for email, xmpp etc.
First your app needs to be paid app, means billing must be enabled for using sockets on GAE
You can have a look here for how to use sockets in java on GAE
Below is the excerpt from google app engine documentation for socket limitations:
App Engine supports sockets without requiring you to import any
special App Engine libraries or add any special App Engine code.
However, there are certain limitations and behaviors you need to be
aware of when using sockets:
Sockets are available only for paid apps.
You cannot create a listen socket; you can only create outbound sockets.
java.net.URL is still configured to use the URL Fetch API; there is currently no way around this.
Most classes in javax.net.ssl are supported.
You can only use TCP or UDP; arbitrary protocols are not allowed.
You cannot bind to specific IP addresses or ports.
Port 25 (SMTP) is blocked; you can still use authenticated SMTP on the submission port 587.
Private, broadcast, multicast, and Google IP ranges (except those whitelisted below), are blocked:
Google Public DNS: 8.8.8.8, 8.8.4.4, 2001:4860:4860::8888, 2001:4860:4860::8844 port 53
Gmail SMTPS: smtp.gmail.com port 465 and 587
Gmail POP3S: pop.gmail.com port 995
Gmail IMAPS: imap.gmail.com port 993
Socket descriptors are associated with the App Engine app that created them and are non-transferable (cannot be used by other apps).
Sockets may be reclaimed after 2 minutes of inactivity; any socket operation keeps the socket alive for a further 2 minutes.
You cannot Select between multiple available sockets because that requires java.nio.SocketChannel which is not currently supported.)
I'm developing a signalr app having a silverlight client and my project structure is
A web app having the server (hub)
a wpf app having the wpf client (for the first client)
a web app for the other web (silverlight) clients
The problem I'm having is that when I try to send a message to other clients in one of the web clients using Firefox or IE, I need to wait around 2 seconds. But if I send another signal or 2 signals in the same time, It works fine. I can assure that my signals are sent on time only if I send 2 messages.
Could this be because of the transport or sthg that I need to configure? Clients are working fine with Chrome.
OK. Forcing the transport to Longpolling has solved my problem.
here is how I start the connection
IClientTransport transport = new LongPollingTransport();
await HubConnection.Start(transport);
You are correct, we have documented the issue on the release notes
Server sent events has known issues on Silverlight
Messages are delayed when using server sent events on silverlight. To force long polling use the following:
connection.Start(new LongPollingTransport());
Thanks in advance for your time and assistance.
I am using Azure Client Library (ie. CloudStorageAccount - CloudBlobClient - CloudBlob) to download/upload blobs in a WPF application.
I would like to set a timeout session in my WPF client application to abort attempt to get a cloud blob. This is different that the server-side timeout that I can set on a blob transfer session. I want to do this as internet connectivity where the application will be used has very unstable intermittent connection.
In other words, I try to do BlobContainer.FetchAttributes before actual data transfer to check internet connectivity. If there is no connection, I do not want to wait 90 odd seconds before it times out and throws an exception.
I have already tried setting timeout in BlobRequestOptions but this does not work as it is applicable only once I have a connection.
Have I understood the settings wrong or is there something else I need to setup/configure/code to achieve a quicker timeout?
I can see in Fiddler that StorageClient library is using HTTP behind the scenes and as per some post I read, I have tried setting timeout in app.config as depicted below. This did not work either.
<configuration>
<system.web>
<httpRuntime executionTimeout="5" />
</system.web>
</configuration>
Sample Timeout using BlobRequest Options:
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
blobContainer = blobClient.GetContainerReference("abcd");
CloudBlob blob = blobContainer.GetBlobReference(aCloudPath);
BlobRequestOptions bro = new BlobRequestOptions()
{ Timeout = TimeSpan.FromSeconds(5) };
blob.DownloadToFile(aLocalPath, bro);
Either options do not work!!
First, changing the httpRuntime executionTimeout in your app.config will not work. This is a setting used server-side by ASP.NET.
Second, the code with the BlobRequestOptions should work, but there's a caveat. By default, the BlobClient comes with an exponential backoff retry policy to handle transient conditions (ie: no network access). Between each retry it will wait a bit and then try again.
If you want to disable this when trying to check for network access, you can simply disable the retry policy:
blobClient.RetryPolicy = () =>
{
return (int currentRetryCount, Exception lastException, out TimeSpan retryInterval) =>
{
retryInterval = TimeSpan.Zero;
return false;
};
};
Be sure to only disable this for when you're testing the network access, don't disable this for your actual requests.
Oh and by the way, why don't you simply use something that already exists to check the internet connection? There are a few APIs available in Windows, like InternetCheckConnection.
And if your connection is unstable, it might be a better idea to improve the retry policy instead of disabling it (look at TOPAZ for example).
If a client is connected and then disconnects - say his connection is lost for 5 mins; does the server queue the messages that can't be delivered?
On the local development server this seems to be the case?
If this is the case in production - how long are the messages queued for?
Thanks
In production the messages are dropped if your server receives the /_ah/channel/disconnected/ POST.
In practice there's a tiny bit of caching. If you eg. lose your connection very briefly because your wifi connection drops, a message sent during that time could be queued up and delivered. But you shouldn't get the disconnect POST in that case.