使用ServiceStack Service的长池请求

时间:2017-08-28 13:05:14

标签: c# servicestack

我希望在HTTP上有一个简单的长池请求,现在的问题是如何才能实现请求连接仍然存在

public async Task<ApiResponse<DeviceLongPoolRequest.Result>> Get(DeviceLongPoolRequest model)
{
    var check = Redis.Get<string>($"dev:check:{model.TokenKey}");
    while (check == null && /****** HERE: Request.IsConnected ******/)
    {
        await Task.Delay(2000);
        check = Redis.Get<string>($"dev:check:{model.TokenKey}");
    }

    return new ApiResponse<DeviceLongPoolRequest.Result>
    {
        Data = new DeviceLongPoolRequest.Result { TokenKey = check }
    };
}

1 个答案:

答案 0 :(得分:2)

没有简单的方法可以确定客户端是否仍然与服务器建立了持久的HTTP连接。像ASP.NET这样的主机仍然表现得像有活动连接,即使客户端不再连接,也可以连续写入HTTP响应。

您可以检查base.Response.IsClosed以确定服务器是否已关闭连接但是您确定不再有活动连接的唯一机会是,如果写入响应流会抛出异常你肯定知道那里不再是一个活跃的连接,但这是不可靠的,并且在很多情况下都不会抛出,因为ASP.NET仍然接受对丢失的客户端连接的写入,如果主机缓冲响应或者更多那是一个中间代理。

我们发现的唯一可靠方法是实施心跳,如果您在任意时间内没有从客户端收到心跳,服务器可以认为连接不再处于活动状态并且可以关闭连接本身。

如果您的长轮询的最长时间仅为短时间(例如<1分钟),您可以假设客户端始终处于连接状态,并且服务将始终执行整个30-60秒,无论他们是&#39 ;是否连接。在较长一段时间内,您不应该使用ServiceStack服务,注册IAppHost.RawHttpHandler并实施ServiceStack ServerEventsFeature之类的自定义听证会。