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> /// </summary>
/// <param name="sessionId">The session identifier.</param> /// <param name="sessionId">The session identifier.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task ReportSessionEnded(string sessionId); void ReportSessionEnded(string sessionId);
/// <summary> /// <summary>
/// Gets the session info dto. /// Gets the session info dto.

View File

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

View File

@ -1,38 +1,44 @@
using System.Collections.Generic; using MediaBrowser.Common.Net;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session; using MediaBrowser.Model.Session;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Session namespace MediaBrowser.Server.Implementations.Session
{ {
public class HttpSessionController : ISessionController public class HttpSessionController : ISessionController, IDisposable
{ {
private readonly IHttpClient _httpClient; private readonly IHttpClient _httpClient;
private readonly IJsonSerializer _json; private readonly IJsonSerializer _json;
private readonly ISessionManager _sessionManager;
public SessionInfo Session { get; private set; } public SessionInfo Session { get; private set; }
private readonly string _postUrl; private readonly string _postUrl;
private Timer _pingTimer;
public HttpSessionController(IHttpClient httpClient, public HttpSessionController(IHttpClient httpClient,
IJsonSerializer json, IJsonSerializer json,
SessionInfo session, SessionInfo session,
string postUrl) string postUrl, ISessionManager sessionManager)
{ {
_httpClient = httpClient; _httpClient = httpClient;
_json = json; _json = json;
Session = session; Session = session;
_postUrl = postUrl; _postUrl = postUrl;
_sessionManager = sessionManager;
_pingTimer = new Timer(PingTimerCallback, null, Timeout.Infinite, Timeout.Infinite);
ResetPingTimer();
} }
public bool IsSessionActive public bool IsSessionActive
@ -48,17 +54,34 @@ namespace MediaBrowser.Server.Implementations.Session
get { return true; } get { return true; }
} }
private Task SendMessage(object obj, CancellationToken cancellationToken) private async void PingTimerCallback(object state)
{ {
var json = _json.SerializeToString(obj); try
return _httpClient.Post(new HttpRequestOptions
{ {
Url = _postUrl, await SendMessage("Ping", CancellationToken.None).ConfigureAwait(false);
CancellationToken = cancellationToken, }
RequestContent = json, catch
RequestContentType = "application/json" {
}); 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) private Task SendMessage(string name, CancellationToken cancellationToken)
@ -66,15 +89,20 @@ namespace MediaBrowser.Server.Implementations.Session
return SendMessage(name, new Dictionary<string, string>(), cancellationToken); 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); var url = _postUrl + "/" + name + ToQueryString(args);
return _httpClient.Post(new HttpRequestOptions await _httpClient.Post(new HttpRequestOptions
{ {
Url = url, Url = url,
CancellationToken = cancellationToken CancellationToken = cancellationToken
});
}).ConfigureAwait(false);
ResetPingTimer();
} }
public Task SendSessionEndedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken) public Task SendSessionEndedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken)
@ -160,5 +188,19 @@ namespace MediaBrowser.Server.Implementations.Session
return "?" + args; 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; return session;
} }
public async Task ReportSessionEnded(string sessionId) public async void ReportSessionEnded(string sessionId)
{ {
await _sessionLock.WaitAsync(CancellationToken.None).ConfigureAwait(false); await _sessionLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
@ -256,18 +256,16 @@ namespace MediaBrowser.Server.Implementations.Session
{ {
var session = GetSession(sessionId); 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))
{
if (_activeConnections.TryRemove(key, out removed)) OnSessionEnded(removed);
{ }
OnSessionEnded(removed);
} }
} }
finally finally
@ -1155,7 +1153,7 @@ namespace MediaBrowser.Server.Implementations.Session
if (controller == null) if (controller == null)
{ {
session.SessionController = new HttpSessionController(_httpClient, _jsonSerializer, session, postUrl); session.SessionController = new HttpSessionController(_httpClient, _jsonSerializer, session, postUrl, this);
} }
} }