// --------------------------------------------------------------------------------------------------------------------
//
// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
//
//
// HandBrake WCF Service
//
// --------------------------------------------------------------------------------------------------------------------
namespace HandBrake.ApplicationServices.Services
{
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Services.Interfaces;
using EncodeCompletedEventArgs = HandBrake.ApplicationServices.EventArgs.EncodeCompletedEventArgs;
using EncodeProgressEventArgs = HandBrake.ApplicationServices.EventArgs.EncodeProgressEventArgs;
///
/// HandBrake WCF Service
///
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IncludeExceptionDetailInFaults = true, ConcurrencyMode = ConcurrencyMode.Single)]
public class ServerService : IServerService
{
#region Constants and Fields
///
/// List of connected Clients. For now, this should only be one.
///
private static readonly List Subscribers = new List();
///
/// The encode service.
///
private static IEncode encodeService;
///
/// The host.
///
private static ServiceHost host;
///
/// The shutdown flag.
///
private static ManualResetEvent shutdownFlag;
#endregion
#region Properties
///
/// Gets the activity log.
///
public string EncodeActivityLog { get; private set; }
///
/// Gets a value indicating whether is encoding.
///
public bool IsEncoding { get; private set; }
///
/// Gets the activity log.
///
public string ScanActivityLog { get; private set; }
#endregion
#region Implemented Interfaces
#region IServerService
///
/// The process encode logs.
///
///
/// The destination.
///
///
/// The configuration.
///
public void ProcessEncodeLogs(string destination, HBConfiguration configuration)
{
encodeService.ProcessLogs(destination, configuration);
}
///
/// Start the service
///
///
/// The port.
///
public void Start(string port)
{
using (host = new ServiceHost(typeof(ServerService), new Uri(string.Format("net.tcp://127.0.0.1:{0}", port))))
{
// Setup a listener
host.AddServiceEndpoint(typeof(IServerService), new NetTcpBinding(), "IHbService");
host.Open();
Console.WriteLine("::: HandBrake Isolation Server - Debug Console:::");
Console.WriteLine("Service Started. Waiting for Clients...");
// Setup the services we are going to use.
encodeService = new LibEncode();
shutdownFlag = new ManualResetEvent(false);
shutdownFlag.WaitOne();
}
}
///
/// Start and Encode
///
///
/// The job.
///
public void StartEncode(QueueTask job)
{
Console.WriteLine("Starting Source Encode for: " + job.Task.Source);
encodeService.EncodeCompleted += this.EncodeServiceEncodeCompleted;
encodeService.EncodeStarted += this.encodeService_EncodeStarted;
encodeService.EncodeStatusChanged += this.encodeService_EncodeStatusChanged;
encodeService.Start(job);
}
///
/// Stop this service
///
public void Stop()
{
if (host != null)
{
host.BeginClose(null, null);
// host.Abort();
shutdownFlag.Set();
}
}
///
/// Stop and Encode
///
public void StopEncode()
{
encodeService.Stop();
}
///
/// The subscribe.
///
///
/// The System.Boolean.
///
public bool Subscribe()
{
try
{
// Get the hashCode of the connecting app and store it as a connection
var callback = OperationContext.Current.GetCallbackChannel();
if (!Subscribers.Contains(callback))
{
Console.WriteLine("Client Connected");
Subscribers.Add(callback);
}
return true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
}
}
///
/// The unsubscribe.
///
///
/// The System.Boolean.
///
public bool Unsubscribe()
{
try
{
var callback = OperationContext.Current.GetCallbackChannel();
if (Subscribers.Contains(callback))
{
Subscribers.Remove(callback);
if (Subscribers.Count == 0)
{
Console.WriteLine("Client Disconnected, Shutting down...");
// Shutdown the service. We no longer have any clients to serve.
// It is the responsibility of the UI to maintain a subscription while this service is in use.
this.Stop();
}
}
return true;
}
catch
{
return false;
}
}
#endregion
#endregion
#region Methods
///
/// The encode service_ encode completed.
///
///
/// The sender.
///
///
/// The e.
///
private void EncodeServiceEncodeCompleted(object sender, EncodeCompletedEventArgs e)
{
encodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;
encodeService.EncodeStarted -= this.encodeService_EncodeStarted;
encodeService.EncodeStatusChanged -= this.encodeService_EncodeStatusChanged;
Subscribers.ForEach(
delegate(IHbServiceCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
Console.WriteLine("Encode Completed Callback");
callback.EncodeCompletedCallback(e);
}
else
{
Subscribers.Remove(callback);
}
});
}
///
/// The encode service_ encode started.
///
///
/// The sender.
///
///
/// The e.
///
private void encodeService_EncodeStarted(object sender, EventArgs e)
{
Subscribers.ForEach(
delegate(IHbServiceCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
Console.WriteLine("Encode Started Callback");
callback.EncodeStartedCallback();
}
else
{
Subscribers.Remove(callback);
}
});
}
///
/// The encode service_ encode status changed.
///
///
/// The sender.
///
///
/// The e.
///
private void encodeService_EncodeStatusChanged(object sender, EncodeProgressEventArgs e)
{
Subscribers.ForEach(
delegate(IHbServiceCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
Console.WriteLine("Encode Status Callback");
callback.EncodeProgressCallback(e);
}
else
{
Subscribers.Remove(callback);
}
});
}
#endregion
}
}