added periodic ping to http session controller

This commit is contained in:
Luke Pulverenti 2014-05-28 11:51:42 -04:00
parent 29ba865ab8
commit cb7fb3ae5c
4 changed files with 76 additions and 36 deletions

View File

@ -99,7 +99,7 @@ namespace MediaBrowser.Controller.Session
/// </summary>
/// <param name="sessionId">The session identifier.</param>
/// <returns>Task.</returns>
Task ReportSessionEnded(string sessionId);
void ReportSessionEnded(string sessionId);
/// <summary>
/// Gets the session info dto.

View File

@ -89,7 +89,7 @@ namespace MediaBrowser.Dlna.PlayTo
try
{
// Session is inactive, mark it for Disposal and don't start the elapsed timer.
await _sessionManager.ReportSessionEnded(_session.Id).ConfigureAwait(false);
_sessionManager.ReportSessionEnded(_session.Id);
}
catch (Exception ex)
{
@ -113,8 +113,8 @@ namespace MediaBrowser.Dlna.PlayTo
string nt;
if (!e.Headers.TryGetValue("NT", out nt)) nt = string.Empty;
if (string.Equals(e.Method, "NOTIFY", StringComparison.OrdinalIgnoreCase) &&
if (string.Equals(e.Method, "NOTIFY", StringComparison.OrdinalIgnoreCase) &&
string.Equals(nts, "ssdp:byebye", StringComparison.OrdinalIgnoreCase) &&
usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1 &&
!_disposed)
@ -124,7 +124,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
try
{
await _sessionManager.ReportSessionEnded(_session.Id).ConfigureAwait(false);
_sessionManager.ReportSessionEnded(_session.Id);
}
catch
{

View File

@ -1,38 +1,44 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
using MediaBrowser.Model.System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Session
{
public class HttpSessionController : ISessionController
public class HttpSessionController : ISessionController, IDisposable
{
private readonly IHttpClient _httpClient;
private readonly IJsonSerializer _json;
private readonly ISessionManager _sessionManager;
public SessionInfo Session { get; private set; }
private readonly string _postUrl;
private Timer _pingTimer;
public HttpSessionController(IHttpClient httpClient,
IJsonSerializer json,
SessionInfo session,
string postUrl)
string postUrl, ISessionManager sessionManager)
{
_httpClient = httpClient;
_json = json;
Session = session;
_postUrl = postUrl;
_sessionManager = sessionManager;
_pingTimer = new Timer(PingTimerCallback, null, Timeout.Infinite, Timeout.Infinite);
ResetPingTimer();
}
public bool IsSessionActive
@ -48,17 +54,34 @@ namespace MediaBrowser.Server.Implementations.Session
get { return true; }
}
private Task SendMessage(object obj, CancellationToken cancellationToken)
private async void PingTimerCallback(object state)
{
var json = _json.SerializeToString(obj);
return _httpClient.Post(new HttpRequestOptions
try
{
Url = _postUrl,
CancellationToken = cancellationToken,
RequestContent = json,
RequestContentType = "application/json"
});
await SendMessage("Ping", CancellationToken.None).ConfigureAwait(false);
}
catch
{
ReportSessionEnded();
}
}
private void ReportSessionEnded()
{
try
{
_sessionManager.ReportSessionEnded(Session.Id);
}
catch (Exception ex)
{
}
}
private void ResetPingTimer()
{
var period = TimeSpan.FromSeconds(60);
_pingTimer.Change(period, period);
}
private Task SendMessage(string name, CancellationToken cancellationToken)
@ -66,15 +89,20 @@ namespace MediaBrowser.Server.Implementations.Session
return SendMessage(name, new Dictionary<string, string>(), cancellationToken);
}
private Task SendMessage(string name, Dictionary<string, string> args, CancellationToken cancellationToken)
private async Task SendMessage(string name,
Dictionary<string, string> args,
CancellationToken cancellationToken)
{
var url = _postUrl + "/" + name + ToQueryString(args);
return _httpClient.Post(new HttpRequestOptions
await _httpClient.Post(new HttpRequestOptions
{
Url = url,
CancellationToken = cancellationToken
});
}).ConfigureAwait(false);
ResetPingTimer();
}
public Task SendSessionEndedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken)
@ -160,5 +188,19 @@ namespace MediaBrowser.Server.Implementations.Session
return "?" + args;
}
public void Dispose()
{
DisposePingTimer();
}
private void DisposePingTimer()
{
if (_pingTimer != null)
{
_pingTimer.Dispose();
_pingTimer = null;
}
}
}
}

View File

@ -248,7 +248,7 @@ namespace MediaBrowser.Server.Implementations.Session
return session;
}
public async Task ReportSessionEnded(string sessionId)
public async void ReportSessionEnded(string sessionId)
{
await _sessionLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
@ -256,18 +256,16 @@ namespace MediaBrowser.Server.Implementations.Session
{
var session = GetSession(sessionId);
if (session == null)
if (session != null)
{
throw new ArgumentException("Session not found");
}
var key = GetSessionKey(session.Client, session.ApplicationVersion, session.DeviceId);
var key = GetSessionKey(session.Client, session.ApplicationVersion, session.DeviceId);
SessionInfo removed;
SessionInfo removed;
if (_activeConnections.TryRemove(key, out removed))
{
OnSessionEnded(removed);
if (_activeConnections.TryRemove(key, out removed))
{
OnSessionEnded(removed);
}
}
}
finally
@ -1155,7 +1153,7 @@ namespace MediaBrowser.Server.Implementations.Session
if (controller == null)
{
session.SessionController = new HttpSessionController(_httpClient, _jsonSerializer, session, postUrl);
session.SessionController = new HttpSessionController(_httpClient, _jsonSerializer, session, postUrl, this);
}
}