如何针对套接字操作设置超时 (HTML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

本主题介绍 如何针对 Windows 运行时应用中的网络套接字操作设置超时,以便对等待操作完成的时间进行限制。

你需要了解的内容

技术

先决条件

  • 以下信息适用于任何使用套接字进行网络连接的联网或感知网络的 Windows 运行时应用。本主题适用于在 Windows 8.1、Windows Phone 8.1 和 Windows Server 2012 上使用 JavaScript 编写的应用。

  • 在本主题中,以下示例都来自 JavaScript。建议对套接字有一个基本的了解。

说明

针对套接字操作设置默认超时的概述

StreamSocket 类实现 Windows 运行时应用中的 TCP 套接字。TCP 套接字必须建立连接才能发送或接收任何网络数据。Windows 8.1、Windows Phone 8.1 和 Windows Server 2012 中实现的基础 TCP 套接字会针对所有的 TCP 连接套接字操作设置默认超时。对于每个来源和目标地址对,在使用主机名或终结点时,默认超时为 3 分钟(180 秒)。因此,如果目标主机名有两个 IP 地址,那么,只有在经过大约 6 分钟之后,连接操作才会超时。对于使用 Windows 运行时应用的客户体验来说,这个默认超时可能过长。因此,使用 StreamSocket 类的应用可能希望针对流套接字连接操作设置较短的自定义超时。

在发送或接收网络数据时,DatagramSocketStreamSocket 类没有默认超时。因此,任何发送或接收操作都将永远等待。使用套接字的 Windows 运行时应用可能希望针对这些操作设置超时以获取更好的客户体验。

StreamSocketListener 类将永远侦听和等待传入的连接请求。

如何针对套接字操作设置自定义超时

JavaScript 语言支持计时事件,这些事件可以按指定的时间间隔执行某些代码。

JavaScript 计时事件

  • setInterval() - 按指定的时间间隔(毫秒)反复执行某个函数。
  • setTimeout() - 在等待指定的毫秒之后执行一次某个函数。

计时事件函数是在 HTML DOM Window 对象中实现的。

WinJS 命名空间为包括 WinJS.Promise 对象的 JavaScript 功能提供特殊的 Windows 库。timeout(timeout, promise) 方法包装 setTimeout 函数。如果在 timeout 参数中指定的毫秒数内未完成承诺,则 Windows 应用商店应用可以使用 timeout(timeout, promise) 方法来取消此承诺。 如果在 timeout 参数中指定的时间间隔内未完成套接字操作,则可以调用 timeout(timeout, promise) 方法并将套接字操作作为 promise 参数以使该操作超时。只要套接字操作仍在挂起,就能将其取消。

WinJS.Promise 对象和 timeout(timeout, promise) 方法可以与 Windows 运行时应用中的任何异步操作一起使用,包括所有的异步套接字操作。 对于正常的完成操作,可以在 timeout(timeout, promise) 方法调用之后添加“.then”。

对于所有这三个类来说,使用超时的基本模型是相同的。 以下讨论使用 StreamSocket 上的连接操作作为示例。在使用 DatagramSocketStreamSocket 对象发送或接收网络数据时,或者在使用 StreamSocketListener 对象侦听传入连接时,可以使用相同的模型来实现超时。

  • 创建一个 StreamSocket
  • 调用 timeout(timeout, promise) 方法并将其中一个 StreamSocket.connectAsync 方法作为 promise 参数。
  • 在源代码的末尾添加 then(successFunction, errorFunction) 方法来处理成功和错误案例。
  • 在出错时,关闭套接字。 在取消 StreamSocket 操作承诺之后,将无法再使用已取消的 StreamSocket

以下示例将针对 StreamSocket 连接操作实现自定义超时。


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;
    }
    ));
}

相关主题

其他

使用套接字进行连接

如何使用数据报套接字进行连接

如何使用流套接字进行连接

如何借助 TLS/SSL 确保套接字连接的安全

参考

DatagramSocket

StreamSocket

StreamSocketListener

timeout(timeout, promise)

Windows.Networking.Sockets

WinJS

WinJS.Promise

示例

承诺示例