From 83946f6878c5db18f31281665f9f6b94c45464f4 Mon Sep 17 00:00:00 2001 From: jwetzell Date: Fri, 5 Apr 2019 13:14:15 -0500 Subject: [PATCH] Migrate All Communication to TCP --- qController.Standard/.DS_Store | Bin 6148 -> 8196 bytes .../Classes/Cell/QSelectedCueOptionsCell.cs | 6 +- .../Classes/Communication/QClient.cs | 45 +++++++ .../Classes/Communication/QController.cs | 24 ++-- .../Classes/Communication/QParser.cs | 41 +++++-- .../Classes/Communication/QReceiver.cs | 4 +- .../Classes/Communication/QUpdater.cs | 16 ++- .../Communication/SharpOSC/TCPSender.cs | 116 +++++++++++------- qController.Standard/Classes/Cues/QCue.cs | 29 ++--- qController.Standard/Classes/Cues/QCueList.cs | 18 +++ .../Classes/Cues/QDefinitions.cs | 10 ++ .../Classes/Cues/QGroupCue.cs | 12 -- .../Classes/Cues/QWorkSpace.cs | 13 ++ .../Pages/ControlPage.xaml.cs | 15 +++ qController.Standard/qController.csproj | 2 + 15 files changed, 250 insertions(+), 101 deletions(-) create mode 100644 qController.Standard/Classes/Communication/QClient.cs create mode 100644 qController.Standard/Classes/Cues/QCueList.cs create mode 100644 qController.Standard/Classes/Cues/QDefinitions.cs delete mode 100644 qController.Standard/Classes/Cues/QGroupCue.cs create mode 100644 qController.Standard/Classes/Cues/QWorkSpace.cs diff --git a/qController.Standard/.DS_Store b/qController.Standard/.DS_Store index b5a7aa7f03bc46f88c6650db6822069c8136aea4..64bb560b3e574157c2e243485e2fa17b9a5969c5 100644 GIT binary patch literal 8196 zcmeHLO>h)N6n-xWp=Tgu5&{_@AzOr$K^M#>se~d#Ha`?nf~3ele_?iKOa^9W!p`h& zLWt&M`NI_yyeSuoDu2s^S{^JfdeJJSO7voR@M5V4FIale*WI&J*ua5{KgIM^zt{bK zdb;0yGjHDl0QTq11b_|zj5_Dq8Y1^-T+jQ8Ru)RQ63HK64h+bEbI|e9E36|y6oDuL zQ3Rq0L=lK0@Lz}k z(EkHIT^9JMfJ!s4@6#PI>cZxB?=`5k(dMkU8| z{QQ7CW?80q%v;4{D(V`2f1P?@!cKecuzlW|(yDzr&El8Z>Jn0=Z(H?W_v zt*lamab?6cGS*FPU3JyQdR?E$rR;M#JDAs+8Ix-@=vx)-eRjg6ogDT|?r92*-k@(| z>^PSXWG$jnthVTnD4M}Wd^(q0;!!oOXudLXmL8&XeOyg2%~VDmBV{>K)Twqc?I~qE zFOMgMwdx+GOr*U`hBoa>S+Bm2X`iuE{Kkh2KR7aLxpZ%SguVt{pXBmB)3i*+SaY&9 z43ft4(Z5$;mS#zc6E}~vr&9TjH za_gp8W243qBd6P28dVJm(TdRSXd!J`sN1=VbmatIscY|08?{x0Q|Z~gTUE6R0u{!EFSr#I?8)w_*&NaXYr)E^Nbg z?7&XK*govTeu1;61{D|i*( zD8bu-BGM$sYb)`VAI`dt=T4J`qjVL$HwH}eZ-0rV7S2&_@W6!tvcw&_EEo`~Uy{AWKHJQ3Rq0{LdnQ6@$Zr{j}-gkBQR# z^IAJb{WNvnxZRTE!i9(^$BBz_oOoD{3)>i(a-U?#mn0_%wSWANfGGbDVU+&`_8w;P EH)5Y4W&i*H delta 122 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{MGjdEU6q~50$jCA=U^gSnWFCRc&81?K7#B9M zE@tQ85M&0b0RjPTAmIv9zOnE-^JIP*O9hZHBLf2ylx6|ZKn}=YkX;O$<9X&V0|2c{ B5e)zU diff --git a/qController.Standard/Classes/Cell/QSelectedCueOptionsCell.cs b/qController.Standard/Classes/Cell/QSelectedCueOptionsCell.cs index e8ba353..930c5f8 100644 --- a/qController.Standard/Classes/Cell/QSelectedCueOptionsCell.cs +++ b/qController.Standard/Classes/Cell/QSelectedCueOptionsCell.cs @@ -61,7 +61,7 @@ namespace qController }; mainSlider.ValueChanged += (sender, args) => { - qController.qSender.sendArgs("/cue/selected/sliderLevel/0", (float)args.NewValue); + qController.qClient.sendArgs("/cue/selected/sliderLevel/0", (float)args.NewValue); }; leftSlider = new Slider @@ -71,7 +71,7 @@ namespace qController }; leftSlider.ValueChanged += (sender, args) => { - qController.qSender.sendArgs("/cue/selected/sliderLevel/1", (float)args.NewValue); + qController.qClient.sendArgs("/cue/selected/sliderLevel/1", (float)args.NewValue); }; rightSlider = new Slider @@ -81,7 +81,7 @@ namespace qController }; rightSlider.ValueChanged += (sender, args) => { - qController.qSender.sendArgs("/cue/selected/sliderLevel/2", (float)args.NewValue); + qController.qClient.sendArgs("/cue/selected/sliderLevel/2", (float)args.NewValue); }; mainG.Children.Add(mainSlider, 1, 0); mainG.Children.Add(leftSlider, 1, 1); diff --git a/qController.Standard/Classes/Communication/QClient.cs b/qController.Standard/Classes/Communication/QClient.cs new file mode 100644 index 0000000..aca4cc0 --- /dev/null +++ b/qController.Standard/Classes/Communication/QClient.cs @@ -0,0 +1,45 @@ +using System; +using SharpOSC; +using Newtonsoft.Json; +namespace qController +{ + public class QClient + { + TCPSender tcpSender; + UDPSender udpSender; + + public QClient(string address, int port) + { + tcpSender = new TCPSender(address, port); + udpSender = new UDPSender(address, port); + } + + public void sendString(string address) + { + tcpSender.Send(new OscMessage(address)); + } + + public OscMessage sendAndReceiveString(string address) + { + return tcpSender.SendAndReceive(new OscMessage(address)); + } + + public OscMessage sendAndReceiveStringArgs(string address, params object[] args) + { + return tcpSender.SendAndReceive(new OscMessage(address, args)); + } + + public void sendStringUDP(string address) + { + udpSender.Send(new OscMessage(address)); + } + public void sendArgs(string address, object args) + { + tcpSender.Send(new OscMessage(address, args)); + } + public void sendArgsUDP(string address, object args) + { + udpSender.Send(new OscMessage(address, args)); + } + } +} diff --git a/qController.Standard/Classes/Communication/QController.cs b/qController.Standard/Classes/Communication/QController.cs index b2cd5c9..1e9968f 100644 --- a/qController.Standard/Classes/Communication/QController.cs +++ b/qController.Standard/Classes/Communication/QController.cs @@ -8,33 +8,32 @@ namespace qController public class QController { - public QSender qSender; - QReceiver qReceiver; QUpdater qUpdater; public QParser qParser; QCue selectedCue; - + public QClient qClient; + QWorkSpace qWorkspace; public QController(string address, int port) { - - qSender = new QSender(address, port); - qReceiver = new QReceiver(port+1, this); + qClient = new QClient(address, port); + qParser = new QParser(); qUpdater = new QUpdater(this); qUpdater.Start(); qParser.SelectedCueUpdated += this.OnSelectedCueUpdated; - qReceiver.MessageReceived += qParser.OnMessageReceived; + qParser.WorkspaceUpdated += this.OnWorkspaceUpdated; + } public void sendCommand(string cmd){ - qSender.sendString(cmd); + qClient.sendString(cmd); } public void sendCommandUDP(string cmd) { - qSender.sendStringUDP(cmd); + qClient.sendStringUDP(cmd); } public void updateCueValue(QCue cue, string property, object newValue){ // qSender.sendArgs("/cue_id/"+cue.uniqueID+"/"+property, newValue); @@ -46,8 +45,13 @@ namespace qController //Console.WriteLine("Selected Cue Updated: Name=" + selectedCue.listName); } + public void OnWorkspaceUpdated(object source, WorkspaceEventArgs args) + { + + qWorkspace = args.UpdatedWorkspace; + + } public void Kill(){ - qReceiver.Close(); qUpdater.Kill(); } } diff --git a/qController.Standard/Classes/Communication/QParser.cs b/qController.Standard/Classes/Communication/QParser.cs index b0eb13f..564deb8 100644 --- a/qController.Standard/Classes/Communication/QParser.cs +++ b/qController.Standard/Classes/Communication/QParser.cs @@ -1,6 +1,7 @@ using System; using SharpOSC; using Newtonsoft.Json.Linq; +using Newtonsoft.Json; namespace qController { @@ -21,7 +22,14 @@ namespace qController set; } } - + public class WorkspaceEventArgs : EventArgs + { + public QWorkSpace UpdatedWorkspace + { + get; + set; + } + } public class QParser { public QParser() @@ -31,9 +39,11 @@ namespace qController public delegate void SelectedCueUpdatedHandler(object source, CueEventArgs args); public delegate void AudioLevelsUpdatedHandler(object source, AudioLevelArgs args); + public delegate void WorkspaceUpdatedHandler(object source, WorkspaceEventArgs args); public event SelectedCueUpdatedHandler SelectedCueUpdated; public event AudioLevelsUpdatedHandler AudioLevelsUpdated; + public event WorkspaceUpdatedHandler WorkspaceUpdated; public void ParseMessage(OscMessage msg){ if (msg.Address.Contains("selectedCues")) @@ -42,19 +52,16 @@ namespace qController ParseNoteInfo(msg); else if (msg.Address.Contains("levels")) ParseLevelInfo(msg); - + else if (msg.Address.Contains("cueLists")) + ParseWorkspaceInfo(msg); + else + Console.WriteLine(msg.Address); } - - public void OnMessageReceived(object source, MessageEventArgs args){ - //Console.WriteLine("Packet Received"); - ParseMessage(args.Message); - } - public void ParseSelectedCueInfo(OscMessage msg){ JArray selectedCues = (JArray)OSC2JSON(msg); - if(selectedCues.Count > 0){ + if (selectedCues.Count > 0){ foreach(JObject item in selectedCues){ - QCue parsedCue = new QCue(item); + QCue parsedCue = JsonConvert.DeserializeObject(item.ToString()); OnSelectedCueUpdated(parsedCue); } @@ -72,11 +79,25 @@ namespace qController OnAudioLevelsUpdated(levels); } + public void ParseWorkspaceInfo(OscMessage msg) + { + if (msg.Arguments.Count > 0) + { + QWorkSpace workspace = JsonConvert.DeserializeObject(msg.Arguments[0].ToString()); + OnWorkspaceUpdated(workspace); + } + } + public JToken OSC2JSON(OscMessage Msg){ JObject json = JObject.Parse(Msg.Arguments.ToArray()[0].ToString()); return json.GetValue("data"); } + protected virtual void OnWorkspaceUpdated(QWorkSpace workspace) + { + if (WorkspaceUpdated != null) + WorkspaceUpdated(this, new WorkspaceEventArgs() { UpdatedWorkspace = workspace }); + } protected virtual void OnSelectedCueUpdated(QCue cue) { if (SelectedCueUpdated != null) diff --git a/qController.Standard/Classes/Communication/QReceiver.cs b/qController.Standard/Classes/Communication/QReceiver.cs index 56de886..a68cf2e 100644 --- a/qController.Standard/Classes/Communication/QReceiver.cs +++ b/qController.Standard/Classes/Communication/QReceiver.cs @@ -44,9 +44,8 @@ namespace qController messageReceived = (OscMessage)udpListener.Receive(); Thread.Sleep(1); } - Console.WriteLine("Received a message!"); - Console.WriteLine(messageReceived.Address); OnMessageReceived(messageReceived); + } Console.WriteLine("Loop Ended"); @@ -59,6 +58,7 @@ namespace qController } protected virtual void OnMessageReceived(OscMessage msg){ + Console.WriteLine("Message Received"); if (MessageReceived != null) MessageReceived(this, new MessageEventArgs(){Message = msg}); } diff --git a/qController.Standard/Classes/Communication/QUpdater.cs b/qController.Standard/Classes/Communication/QUpdater.cs index 2bb02a5..f2d4345 100644 --- a/qController.Standard/Classes/Communication/QUpdater.cs +++ b/qController.Standard/Classes/Communication/QUpdater.cs @@ -1,5 +1,6 @@ using System; using Xamarin.Forms; +using SharpOSC; namespace qController { public class QUpdater @@ -14,10 +15,21 @@ namespace qController public void Start(){ active = true; Device.StartTimer(TimeSpan.FromSeconds(0.01), () => { - qController.sendCommandUDP("/selectedCues"); - qController.sendCommandUDP("/cue/selected/levels"); + //qController.sendCommandUDP("/selectedCues"); + UpdateSelected(); + UpdateLevels(); return active; }); + + } + + public void UpdateSelected() + { + qController.qParser.ParseMessage(qController.qClient.sendAndReceiveString("/selectedCues")); + } + public void UpdateLevels() + { + qController.qParser.ParseMessage(qController.qClient.sendAndReceiveString("/cue/selected/levels")); } public void Kill(){ diff --git a/qController.Standard/Classes/Communication/SharpOSC/TCPSender.cs b/qController.Standard/Classes/Communication/SharpOSC/TCPSender.cs index ef47e5e..2cd1ba6 100644 --- a/qController.Standard/Classes/Communication/SharpOSC/TCPSender.cs +++ b/qController.Standard/Classes/Communication/SharpOSC/TCPSender.cs @@ -3,9 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; -using System.Net; using System.Threading; -using System.IO; namespace SharpOSC { @@ -22,8 +20,8 @@ namespace SharpOSC get { return _address; } } string _address; - TcpClient client; + Thread receivingThread; byte END = 0xc0; byte ESC = 0xdb; @@ -35,70 +33,106 @@ namespace SharpOSC { _port = port; _address = address; - } public void Send(byte[] message) { client = new TcpClient(Address, Port); - Console.WriteLine("Available: " + client.Available); - Console.WriteLine("Connected: " + client.Connected); - List slipData= new List(); - - byte[] esc_end = { ESC, ESC_END }; - byte[] esc_esc = { ESC, ESC_ESC }; - byte[] end = { END }; - - int length = message.Length; - for (int i = 0; i < length; i++) - { - if (message[i] == END) - { - slipData.AddRange(esc_end); - } else if (message[i] == ESC) - { - slipData.AddRange(esc_esc); - } - else - { - slipData.Add(message[i]); - } - } - slipData.AddRange(end); + byte[] slipData = SlipEncode(message); NetworkStream netStream = client.GetStream(); netStream.Write(slipData.ToArray(), 0, slipData.ToArray().Length); netStream.Close(); client.Close(); } - public void Receive() + public OscMessage Receive() { - NetworkStream netStream = client.GetStream(); - List responseData = new List(); - if (netStream.CanRead) + OscMessage response = new OscMessage("/null"); + try { - byte[] buffer = new byte[512]; - - int bytesRead = 0; - do + NetworkStream netStream = client.GetStream(); + netStream.ReadTimeout = 250; + List responseData = new List(); + if (netStream.CanRead) { - bytesRead = netStream.Read(buffer, 0, buffer.Length); - responseData.AddRange(buffer); + byte[] buffer = new byte[1024]; - } while (netStream.DataAvailable); - OscMessage response = (OscMessage)OscPacket.GetPacket(responseData.Skip(1).ToArray()); + int bytesRead = 0; + do + { + bytesRead = netStream.Read(buffer, 0, buffer.Length); + responseData.AddRange(buffer); + } while (netStream.DataAvailable); + response = (OscMessage)OscPacket.GetPacket(responseData.Skip(1).ToArray()); + netStream.Close(); + client.Close(); + } + } catch(Exception e) + { + Console.WriteLine(e.ToString()); } - netStream.Close(); + return response; } + + public OscMessage SendAndReceive(byte[] message) + { + client = new TcpClient(Address, Port); + byte[] slipData = SlipEncode(message); + NetworkStream netStream = client.GetStream(); + netStream.Write(slipData.ToArray(), 0, slipData.ToArray().Length); + OscMessage response = Receive(); + return response; + } + + public OscMessage SendAndReceive(OscPacket packet) + { + byte[] data = packet.GetBytes(); + OscMessage response = SendAndReceive(data); + return response; + } + public void StartReceiving() + { + receivingThread.Start(); + } + public void Send(OscPacket packet) { byte[] data = packet.GetBytes(); Send(data); } + public byte[] SlipEncode(byte[] data) + { + List slipData = new List(); + + byte[] esc_end = { ESC, ESC_END }; + byte[] esc_esc = { ESC, ESC_ESC }; + byte[] end = { END }; + + int length = data.Length; + for (int i = 0; i < length; i++) + { + if (data[i] == END) + { + slipData.AddRange(esc_end); + } + else if (data[i] == ESC) + { + slipData.AddRange(esc_esc); + } + else + { + slipData.Add(data[i]); + } + } + slipData.AddRange(end); + return slipData.ToArray(); + } + public void Close() { client.GetStream().Close(); + receivingThread.Abort(); client.Close(); } } diff --git a/qController.Standard/Classes/Cues/QCue.cs b/qController.Standard/Classes/Cues/QCue.cs index 7f78e74..e044a0d 100644 --- a/qController.Standard/Classes/Cues/QCue.cs +++ b/qController.Standard/Classes/Cues/QCue.cs @@ -4,26 +4,13 @@ namespace qController { public class QCue { - public string number; - public string uniqueID; - public bool flagged; - public string listName; - public string type; - public string colorName; - public string name; - public bool armed; - - public QCue(JObject json){ - //Console.WriteLine(json); - number = (string)json.GetValue("number"); - uniqueID = (string)json.GetValue("uniqueID"); - flagged = (bool)json.GetValue("flagged"); - listName = (string)json.GetValue("listName"); - type = (string)json.GetValue("type"); - colorName = (string)json.GetValue("colorName"); - name = (string)json.GetValue("name"); - armed = (bool)json.GetValue("armed"); - } - + public string number { get; set; } + public string uniqueID { get; set; } + public bool flagged { get; set; } + public string listName { get; set; } + public string type { get; set; } + public string colorName { get; set; } + public string name { get; set; } + public bool armed { get; set; } } } diff --git a/qController.Standard/Classes/Cues/QCueList.cs b/qController.Standard/Classes/Cues/QCueList.cs new file mode 100644 index 0000000..9d7883c --- /dev/null +++ b/qController.Standard/Classes/Cues/QCueList.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace qController +{ + public class QCueList + { + public string number { get; set; } + public string uniqueID { get; set; } + public List cues { get; set; } + public bool flagged { get; set; } + public string listName { get; set; } + public string type { get; set; } + public string colorName { get; set; } + public string name { get; set; } + public bool armed { get; set; } + } +} diff --git a/qController.Standard/Classes/Cues/QDefinitions.cs b/qController.Standard/Classes/Cues/QDefinitions.cs new file mode 100644 index 0000000..b990bbd --- /dev/null +++ b/qController.Standard/Classes/Cues/QDefinitions.cs @@ -0,0 +1,10 @@ +using System; +namespace qController.Classes.Cues +{ + public class QDefinitions + { + public QDefinitions() + { + } + } +} diff --git a/qController.Standard/Classes/Cues/QGroupCue.cs b/qController.Standard/Classes/Cues/QGroupCue.cs deleted file mode 100644 index f544fb4..0000000 --- a/qController.Standard/Classes/Cues/QGroupCue.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Newtonsoft.Json.Linq; -namespace qController -{ - public class QGroupCue : QCue - { - - public QGroupCue(JObject json) : base(json) - { - - } - } -} diff --git a/qController.Standard/Classes/Cues/QWorkSpace.cs b/qController.Standard/Classes/Cues/QWorkSpace.cs new file mode 100644 index 0000000..ae33751 --- /dev/null +++ b/qController.Standard/Classes/Cues/QWorkSpace.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace qController +{ + public class QWorkSpace + { + public string status { get; set; } + public List data { get; set; } + public string workspace_id { get; set; } + public string address { get; set; } + } +} diff --git a/qController.Standard/Pages/ControlPage.xaml.cs b/qController.Standard/Pages/ControlPage.xaml.cs index 2da1001..ce73183 100644 --- a/qController.Standard/Pages/ControlPage.xaml.cs +++ b/qController.Standard/Pages/ControlPage.xaml.cs @@ -18,6 +18,9 @@ namespace qController qController = new QController(address, 53000); qController.qParser.SelectedCueUpdated += SelectedCueUpdated; + qController.qParser.WorkspaceUpdated += WorkspaceUpdated; + + qController.qParser.ParseWorkspaceInfo(qController.qClient.sendAndReceiveString("/cueLists")); NavigationPage.SetHasNavigationBar(this, false); instanceName.Text = name; @@ -145,6 +148,18 @@ namespace qController }); } + public void WorkspaceUpdated(object sender, WorkspaceEventArgs e) + { + if(e.UpdatedWorkspace.data.Count > 0) + { + Device.BeginInvokeOnMainThread(() => + { + // + }); + Console.WriteLine("Workspace Updated: " + e.UpdatedWorkspace.workspace_id); + } + } + protected override void OnDisappearing() { base.OnDisappearing(); diff --git a/qController.Standard/qController.csproj b/qController.Standard/qController.csproj index b78845f..e6f31af 100644 --- a/qController.Standard/qController.csproj +++ b/qController.Standard/qController.csproj @@ -35,6 +35,8 @@ + +