How to set timeouts on socket operations (HTML)

This topic shows how to set timeouts on network socket operations in a Windows Runtime app to limit the time to wait for an operation to complete.

What you need to know

Technologies

Prerequisites

  • The following information applies to any connected or network-aware Windows Runtime app that uses sockets for network connections. This topic applies to apps written in JavaScript on Windows 8.1, Windows Phone 8.1, and Windows Server 2012.

  • The following examples in this topic are provided in JavaScript. A basic understanding of sockets is recommended.

Instructions

Overview of default timeouts on socket operations

The StreamSocket class implements a TCP socket in a Windows Runtime app. A TCP socket must establish a connection before any network data can be sent or received. The underlying TCP socket implementation in Windows 8.1, Windows Phone 8.1, and Windows Server 2012 sets a default timeout on any TCP connect socket operations. The default timeout is 3 minutes (180 seconds) for each source and destination address pair when hostnames or endpoints are used. So if a destination hostname has two IP addresses, then the connect operation would not timeout until about 6 minutes have elapsed. This default timeout may well be excessive for the customer experience using a Windows Runtime app. So an app using the StreamSocket class may want to set a shorter custom timeout on stream socket connect operations.

The DatagramSocket and StreamSocket classes do not have any default timeouts when sending or receiving network data. So any send or receive operation will wait forever. A Windows Runtime app using sockets may want to set a timeout on these operations for a better customer experience.

The StreamSocketListener class will listen and wait forever for incoming connection requests.

How to set custom timeouts on socket operations

The JavaScript language supports timing events that make it is possible to execute some code at specified time intervals.

JavaScript timing events

  • setInterval() - Executes a function repeatedly at specified time intervals in milliseconds.
  • setTimeout() - Executes a function once after waiting specified number of milliseconds.

The timing event functions are implemented in the HTML DOM Window object.

The WinJS namespace provides special Windows Library for JavaScript features that includes a WinJS.Promise object. The timeout(timeout, promise) method wraps the setTimeout function. The timeout(timeout, promise) method can be used by a Windows Store app to cancel a promise if it hasn’t completed by the number of milliseconds specified in the timeout parameter. The timeout(timeout, promise) method can be called with a socket operation as the promise parameter to timeout the operation if it hasn't completed within the interval specified by the timeout parameter. The socket operation is able to be cancelled as long as the operation is still pending.

The WinJS.Promise object and the timeout(timeout, promise) method can be used with any of the asynchronous operations in a Windows Runtime app, including all of the asynchronous socket operations. You can add a “.then” after the timeout(timeout, promise) method call for your normal completions.

The basic model to use timeouts is the same for all three classes. The discussion below uses a connect operation on a StreamSocket as an example. The same model can be used to implement timeouts when sending or receiving network data with the DatagramSocket or StreamSocket object or when listening for incoming connections with a StreamSocketListener object.

  • Create a StreamSocket.
  • Call the timeout(timeout, promise) method with one of the StreamSocket.connectAsync methods as the promise parameter.
  • Finish the source code by adding a .then(successFunction, errorFunction) method to handle success and error cases.
  • On error, close the socket. Once a StreamSocket operation promise is cancelled, the StreamSocket that was cancelled can no longer be used.

The following sample implements a custom timeout on a StreamSocket connect operation.


var clientSocket = null;
var timeout = 10000; // 10 seconds
function openClient() {
    var serverHostName = new Windows.Networking.HostName("www.contoso.com");
    var serviceName = "http";
 
    // displayStatus("Client: connection started.");
    clientSocket = new Windows.Networking.Sockets.StreamSocket();
    //var promise = clientSocket.connectAsync(serverHostName, serviceName)
    WinJS.Promise.timeout(timeout, clientSocket.connectAsync(serverHostName, serviceName).then(function () {
        // displayStatus("Client: connection completed.");
        // Do your socket operations here.
 
    }, function (reason) {
        // There are many reasons for this failure: the promise might have 
        // timed out, or the server host refused the connection, or there
        // was an TCP issue, or several other possibilities.
 
        // displayStatus("Client: connection failed. ");
        // displayStatus(reason.message);
        clientSocket.close();
        clientSocket = null;
    }
    ));
}

Other

Connecting with sockets

How to connect with a datagram socket

How to connect with a stream socket

How to secure socket connections with TLS/SSL

Reference

DatagramSocket

StreamSocket

StreamSocketListener

timeout(timeout, promise)

Windows.Networking.Sockets

WinJS

WinJS.Promise

Samples

Promise sample