diff --git a/GazeWebSocketServer.sln b/GazeWebSocketServer.sln index 9b2d5ef..b754b70 100644 --- a/GazeWebSocketServer.sln +++ b/GazeWebSocketServer.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.29209.62 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GazeWebSocketServer", "GazeWebSocketServer\GazeWebSocketServer.csproj", "{F8F11E64-7946-4054-8C27-F0FCAF967F1A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrackerBridge", "TrackerBridge\TrackerBridge.csproj", "{64D52257-ECA7-4F4D-A901-B14D544A1D0A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {F8F11E64-7946-4054-8C27-F0FCAF967F1A}.Debug|Any CPU.Build.0 = Debug|Any CPU {F8F11E64-7946-4054-8C27-F0FCAF967F1A}.Release|Any CPU.ActiveCfg = Release|Any CPU {F8F11E64-7946-4054-8C27-F0FCAF967F1A}.Release|Any CPU.Build.0 = Release|Any CPU + {64D52257-ECA7-4F4D-A901-B14D544A1D0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {64D52257-ECA7-4F4D-A901-B14D544A1D0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {64D52257-ECA7-4F4D-A901-B14D544A1D0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {64D52257-ECA7-4F4D-A901-B14D544A1D0A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/GazeWebSocketServer/EyeTrackerClient.cs b/GazeWebSocketServer/EyeTrackerClient.cs deleted file mode 100644 index 91f84ab..0000000 --- a/GazeWebSocketServer/EyeTrackerClient.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tobii.Research; - -namespace GazeWebSocketServer -{ - class EyeTrackerClient - { - private IEyeTracker eyeTracker; - private GazeDataProcessor gazeDataProcessor; - private List gazeCoordinateBehaviors; - - public EyeTrackerClient(ConfigurationData config) - { - gazeCoordinateBehaviors = new List(); - while (eyeTracker == null) - { - EyeTrackerCollection eyeTrackers = EyeTrackingOperations.FindAllEyeTrackers(); - if (eyeTrackers.Count > 0) - { - foreach(IEyeTracker t in eyeTrackers) - { - if(config.TrackerSerialNumber == t.SerialNumber) - { - eyeTracker = t; - } - } - } - } - gazeDataProcessor = new GazeDataProcessor(); - eyeTracker.SetGazeOutputFrequency(config.TrackerFrequency); - } - - public void Start(GazeCoordinateBehavior gazeCoordinateBehavior) - { - gazeCoordinateBehaviors.Add(gazeCoordinateBehavior); - eyeTracker.GazeDataReceived += GazeDataReceivedHandler; - } - - public void Stop() - { - eyeTracker.GazeDataReceived -= GazeDataReceivedHandler; - } - - private void GazeDataReceivedHandler(object sender, GazeDataEventArgs e) - { - GazeData gazeData = gazeDataProcessor.Extract(e); - foreach(GazeCoordinateBehavior behavior in gazeCoordinateBehaviors) - { - behavior.Publish(gazeData); - } - Console.WriteLine(gazeData.ToString()); - } - } -} \ No newline at end of file diff --git a/GazeWebSocketServer/GazeCoordinateBehavior.cs b/GazeWebSocketServer/GazeCoordinateBehavior.cs index 52dd255..e3c05fb 100644 --- a/GazeWebSocketServer/GazeCoordinateBehavior.cs +++ b/GazeWebSocketServer/GazeCoordinateBehavior.cs @@ -3,34 +3,15 @@ using WebSocketSharp; using WebSocketSharp.Server; using System.Collections.Generic; using System.Text; +using TrackerBridge; namespace GazeWebSocketServer { public class GazeCoordinateBehavior : WebSocketBehavior { - private EyeTrackerClient eyeTrackerClient; - - public GazeCoordinateBehavior(ConfigurationData config) + public GazeCoordinateBehavior() { Console.WriteLine("Creating behavior..."); - eyeTrackerClient = new EyeTrackerClient(config); - eyeTrackerClient.Start(this); - } - - //~GazeCoordinateBehavior() - //{ - // eyeTrackerClient.Stop(); - //} - - //protected override void OnOpen() - //{ - // throw new NotImplementedException(); - // //base.OnOpen(); - //} - - internal void Publish(GazeData gazeData) - { - Sessions?.Broadcast(gazeData.ToString()); } } } diff --git a/GazeWebSocketServer/GazeServer.cs b/GazeWebSocketServer/GazeServer.cs new file mode 100644 index 0000000..f431e96 --- /dev/null +++ b/GazeWebSocketServer/GazeServer.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WebSocketSharp.Server; +using TrackerBridge; + +namespace GazeWebSocketServer +{ + class GazeServer + { + private WebSocketServer wssv; + public GazeServer(Int32 port, String endpoint) + { + wssv = new WebSocketServer(port); + wssv.Log.Level = WebSocketSharp.LogLevel.Trace; + wssv.AddWebSocketService(endpoint, () => new GazeCoordinateBehavior()); + } + public void Start() + { + wssv.Start(); + } + + public void Publish(GazeData gazeData) + { + WebSocketServiceManager wssm = wssv.WebSocketServices; + foreach(WebSocketServiceHost serviceHost in wssm.Hosts) + { + if (serviceHost.Type == typeof(GazeCoordinateBehavior)) + { + serviceHost.Sessions?.Broadcast(gazeData.ToString()); + } + } + } + } +} diff --git a/GazeWebSocketServer/GazeWebSocketServer.csproj b/GazeWebSocketServer/GazeWebSocketServer.csproj index b75a431..3b325fb 100644 --- a/GazeWebSocketServer/GazeWebSocketServer.csproj +++ b/GazeWebSocketServer/GazeWebSocketServer.csproj @@ -54,10 +54,8 @@ - - - + @@ -66,6 +64,12 @@ + + + {64d52257-eca7-4f4d-a901-b14d544a1d0a} + TrackerBridge + + diff --git a/GazeWebSocketServer/Program.cs b/GazeWebSocketServer/Program.cs index 19003e0..045f672 100644 --- a/GazeWebSocketServer/Program.cs +++ b/GazeWebSocketServer/Program.cs @@ -1,25 +1,48 @@ using System; +using System.Threading.Tasks; +using System.Threading; using WebSocketSharp; using WebSocketSharp.Server; using Tobii.Research; +using TrackerBridge; namespace GazeWebSocketServer { public class Program { + private static GazeServer gazeServer; public static void Main(string[] args) { ConfigurationData.InitializeUnexistingWithDefaults(); ConfigurationData config = ConfigurationData.ParseToObject(); - var wssv = new WebSocketServer(config.WebSocketPort); - wssv.KeepClean = true; - GazeCoordinateBehavior behavior = new GazeCoordinateBehavior(config); - wssv.AddWebSocketService(config.WebSocketEndpoint, () => behavior); - - wssv.Start(); - Console.ReadKey(true); - wssv.Stop(); + TobiiEyeTracker tobiiEyeTracker = new TobiiEyeTracker(config.TrackerSerialNumber); + tobiiEyeTracker.ConnectionEvent += OnConnectionEstablished; + tobiiEyeTracker.ConnectionTimeout += OnConnectionTimeout; + tobiiEyeTracker.GazeDataAvailable += OnGazeDataAvailable; + tobiiEyeTracker.Connect(); + + gazeServer = new GazeServer(config.WebSocketPort, config.WebSocketEndpoint); + gazeServer.Start(); + Console.ReadLine(); + } + + private static void OnGazeDataAvailable(TobiiEyeTracker sender, GazeData data) + { + Console.WriteLine(data); + gazeServer.Publish(data); + } + + private static void OnConnectionTimeout(TobiiEyeTracker sender) + { + Console.WriteLine("Timeout while searching for trackers."); + } + + private static void OnConnectionEstablished(TobiiEyeTracker sender) + { + Console.WriteLine($"Tracker {sender.ToString()} connected."); + ConfigurationData config = ConfigurationData.ParseToObject(); + sender.SetTrackingFrequency(config.TrackerFrequency); } } } \ No newline at end of file diff --git a/TobiiBridge/Class1.cs b/TobiiBridge/Class1.cs new file mode 100644 index 0000000..a84680e --- /dev/null +++ b/TobiiBridge/Class1.cs @@ -0,0 +1,17 @@ +using System; + +namespace TobiiBridge +{ + public class EyeTracker + { + public EyeTracker() + { + + } + + public EyeTracker(String serialNumber) + { + + } + } +} diff --git a/TobiiBridge/TobiiBridge.csproj b/TobiiBridge/TobiiBridge.csproj new file mode 100644 index 0000000..b9a4f46 --- /dev/null +++ b/TobiiBridge/TobiiBridge.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + + + + x64 + + + + + + + diff --git a/GazeWebSocketServer/GazeData.cs b/TrackerBridge/GazeData.cs similarity index 93% rename from GazeWebSocketServer/GazeData.cs rename to TrackerBridge/GazeData.cs index c9db035..152a70b 100644 --- a/GazeWebSocketServer/GazeData.cs +++ b/TrackerBridge/GazeData.cs @@ -4,9 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace GazeWebSocketServer +namespace TrackerBridge { - struct GazeData + public struct GazeData { public readonly float leftX; public readonly float leftY; diff --git a/GazeWebSocketServer/GazeDataProcessor.cs b/TrackerBridge/GazeDataProcessor.cs similarity index 93% rename from GazeWebSocketServer/GazeDataProcessor.cs rename to TrackerBridge/GazeDataProcessor.cs index adc6a58..ca6545a 100644 --- a/GazeWebSocketServer/GazeDataProcessor.cs +++ b/TrackerBridge/GazeDataProcessor.cs @@ -6,9 +6,9 @@ using System.Text; using System.Threading.Tasks; using Tobii.Research; -namespace GazeWebSocketServer +namespace TrackerBridge { - class GazeDataProcessor + public class GazeDataProcessor { readonly float screenHeight; readonly float screenWidth; diff --git a/TrackerBridge/Properties/AssemblyInfo.cs b/TrackerBridge/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d0d63ba --- /dev/null +++ b/TrackerBridge/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die einer Assembly zugeordnet sind. +[assembly: AssemblyTitle("TrackerBridge")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("OTH Regensburg")] +[assembly: AssemblyProduct("TrackerBridge")] +[assembly: AssemblyCopyright("Copyright © OTH Regensburg 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly +// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von +// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("64d52257-eca7-4f4d-a901-b14d544a1d0a")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, +// indem Sie "*" wie unten gezeigt eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TrackerBridge/TobiiEyeTracker.cs b/TrackerBridge/TobiiEyeTracker.cs new file mode 100644 index 0000000..e7fe5c9 --- /dev/null +++ b/TrackerBridge/TobiiEyeTracker.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tobii.Research; + +namespace TrackerBridge +{ + public class TobiiEyeTracker + { + public delegate void ConnectionEventHandler(TobiiEyeTracker sender); + public delegate void GazeDataHandler(TobiiEyeTracker sender, GazeData data); + public event ConnectionEventHandler ConnectionEvent; + public event ConnectionEventHandler ConnectionTimeout; + public event GazeDataHandler GazeDataAvailable; + + public Boolean IsConnected { get; private set; } + + private IEyeTracker eyeTracker = null; + private String serialNumber = null; + private GazeDataProcessor gazeDataProcessor; + + public TobiiEyeTracker() + { + gazeDataProcessor = new GazeDataProcessor(); + } + + public TobiiEyeTracker(String serialNumber) : this() + { + this.serialNumber = serialNumber; + } + + public float GetTrackingFrequency() + { + if (eyeTracker != null) + { + return eyeTracker.GetGazeOutputFrequency(); + } + else + { + throw new NullReferenceException(); + } + } + public void SetTrackingFrequency(float value) + { + if (eyeTracker != null) + { + eyeTracker.SetGazeOutputFrequency(value); + } + } + + public void Connect() + { + Task task = new Task(() => InitiateConnection()); + task.Start(); + } + + private void InitiateConnection() + { + DateTime time = DateTime.Now; + while (eyeTracker == null) + { + EyeTrackerCollection eyeTrackers = EyeTrackingOperations.FindAllEyeTrackers(); + if (eyeTrackers.Count > 0) + { + if (serialNumber == null) + { + eyeTracker = eyeTrackers[0]; + break; + } + else + { + foreach (IEyeTracker t in eyeTrackers) + { + if (serialNumber == t.SerialNumber) + { + eyeTracker = t; + break; + } + } + } + } + + if (eyeTracker != null) + { + break; + } + + if ((DateTime.Now - time) > (new TimeSpan(0, 0, 30))) + { + ConnectionTimeout?.Invoke(this); + } + } + eyeTracker.GazeDataReceived += OnGazeDataReceived; + SetTrackingFrequency(600f); + ConnectionEvent?.Invoke(this); + } + + private void OnGazeDataReceived(object sender, GazeDataEventArgs e) + { + GazeData gazeData = gazeDataProcessor.Extract(e); + GazeDataAvailable?.Invoke(this, gazeData); + } + } +} \ No newline at end of file diff --git a/TrackerBridge/TrackerBridge.csproj b/TrackerBridge/TrackerBridge.csproj new file mode 100644 index 0000000..2b99db3 --- /dev/null +++ b/TrackerBridge/TrackerBridge.csproj @@ -0,0 +1,67 @@ + + + + + Debug + AnyCPU + {64D52257-ECA7-4F4D-A901-B14D544A1D0A} + Library + Properties + TrackerBridge + TrackerBridge + v4.7.2 + 512 + true + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x64 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + ..\packages\Tobii.Research.x64.1.7.0.1070\lib\net452\Tobii.Research.dll + + + + + + + + + + + + + + + + Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}". + + + + \ No newline at end of file diff --git a/TrackerBridge/packages.config b/TrackerBridge/packages.config new file mode 100644 index 0000000..03fedc7 --- /dev/null +++ b/TrackerBridge/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file