async private void StreamBtn_Click(object sender, EventArgs e) { if (!IsStreamingMQTT) { recordingCount++; long startTime = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeMilliseconds(); //current start time when we button is clicked var topic = mqttTopic; var factory = new MqttFactory(); var mqttClient = factory.CreateMqttClient(); string mqttText = MQTTIPTextBox.Text; // Use WebSocket connection. var options = new MqttClientOptionsBuilder() .WithClientId("Tobii RET") .WithWebSocketServer(mqttText) //"broker.hivemq.com:8000/mqtt" .WithTls() //For wss .Build(); await mqttClient.ConnectAsync(options, CancellationToken.None); // Since 3.0.5 with CancellationToken //TODO figure out how to setup the disconnect handler to reconnect as needed. //The wiki seems to not be updated on this point /*mqttClient.UseDisconnectedHandler = (async e => * { * Console.WriteLine("### DISCONNECTED FROM SERVER ###"); * await Task.Delay(TimeSpan.FromSeconds(5)); * * try * { * await mqttClient.ConnectAsync(options, CancellationToken.None); // Since 3.0.5 with CancellationToken * } * catch * { * Console.WriteLine("### RECONNECTING FAILED ###"); * } * });*/ SelectedTracker.GazeDataReceived += HandleGazeData; IsStreamingMQTT = true; Form FixationForm = new Form(); FixationForm.ControlBox = false; FixationForm.WindowState = FormWindowState.Normal; FixationForm.FormBorderStyle = FormBorderStyle.None; FixationForm.WindowState = FormWindowState.Maximized; FixationForm.Show(); Panel AnimatedPointPanel = new Panel(); AnimatedPointPanel.Width = FixationForm.Width; AnimatedPointPanel.Height = FixationForm.Height; Graphics AnimatedPointGraphics = AnimatedPointPanel.CreateGraphics(); FixationForm.Controls.Add(AnimatedPointPanel); int w = FixationForm.Width; int h = FixationForm.Height; MQTTThread = new Thread(async() => { int sampleCount = 0; var dataList = new List <object>(); //for later adding object in GazeDataEventArgs prevGazeDataEvent = null; while (IsStreamingMQTT) { try { while (GazeEventQueue.Any()) { GazeDataEventArgs currentgazeEvent; GazeEventQueue.TryDequeue(out currentgazeEvent); double velocity = VelocityCalculation.CalculateVelocity(prevGazeDataEvent, currentgazeEvent, "Average"); Console.WriteLine(velocity); float gazeX = 0; float gazeY = 0; if (currentgazeEvent.LeftEye.GazePoint.Validity == Validity.Valid && currentgazeEvent.RightEye.GazePoint.Validity == Validity.Valid) { gazeX = (currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X + currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X) / 2; gazeY = (currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y + currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y) / 2; } else if (currentgazeEvent.LeftEye.GazePoint.Validity == Validity.Valid) { gazeX = currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X; gazeY = currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y; } else if (currentgazeEvent.RightEye.GazePoint.Validity == Validity.Valid) { gazeX = currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X; gazeY = currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y; } if (velocity >= Threshold) { int radius = 10; Console.Write("--> Fixation "); Console.WriteLine(gazeX.ToString() + "\t" + gazeY.ToString()); Console.WriteLine(gazeX * w); Console.WriteLine(gazeY * h); AnimatedPointGraphics.DrawEllipse(CalBrush, gazeX * w - radius, gazeY * h - radius, radius + radius, radius + radius); } if (currentgazeEvent.LeftEye.Pupil.PupilDiameter != -1 || currentgazeEvent.RightEye.Pupil.PupilDiameter != -1) { CurrentPupilDiameters[0] = Double.IsNaN(currentgazeEvent.LeftEye.Pupil.PupilDiameter) ? -1 : currentgazeEvent.LeftEye.Pupil.PupilDiameter; CurrentPupilDiameters[1] = Double.IsNaN(currentgazeEvent.RightEye.Pupil.PupilDiameter) ? -1 : currentgazeEvent.RightEye.Pupil.PupilDiameter; } var dataObject = new Dictionary <string, object>(); dataObject.Add("timestamp", currentgazeEvent.DeviceTimeStamp); dataObject.Add("sampleCount", sampleCount); dataObject.Add("gaze", new Dictionary <string, float> { { "x", gazeX }, { "y", gazeY } } ); dataObject.Add("pupilDiameter", new Dictionary <string, double> { { "LeftEye", CurrentPupilDiameters[0] }, { "RightEye", CurrentPupilDiameters[1] } } ); //GazePoint in data var GazePointObject = new Dictionary <string, object>(); GazePointObject.Add("LeftEye", new Dictionary <string, float> { { "x", float.IsNaN(currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X) ? float.NaN : currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X }, { "y", float.IsNaN(currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y) ? float.NaN : currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y } } ); GazePointObject.Add("RightEye", new Dictionary <string, float> { { "x", float.IsNaN(currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X) ? float.NaN : currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X }, { "y", float.IsNaN(currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y) ? float.NaN : currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y } } ); dataObject.Add("GazePoint_PositionOnDisplayArea", GazePointObject); //GazeOrigin in data var GazeOriginObject = new Dictionary <string, object>(); GazeOriginObject.Add("LeftEye", new Dictionary <string, float> { { "x", float.IsNaN(currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.X) ? float.NaN : currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.X }, { "y", float.IsNaN(currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Y) ? float.NaN : currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Y }, { "z", float.IsNaN(currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Z) ? float.NaN : currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Z } } ); GazeOriginObject.Add("RightEye", new Dictionary <string, float> { { "x", float.IsNaN(currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.X) ? float.NaN : currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.X }, { "y", float.IsNaN(currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Y) ? float.NaN : currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Y }, { "z", float.IsNaN(currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Z) ? float.NaN : currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Z } } ); dataObject.Add("GazeOrigin_PositionInUserCoordinates", GazeOriginObject); sampleCount++; dataList.Add(dataObject); //append to the list prevGazeDataEvent = currentgazeEvent; if (dataList.Count == BatchSize) { //create a dict-shape message, later will be serialized as a json object var msg = new Dictionary <string, object>(); msg.Add("user", new Dictionary <string, Guid> { { "uid", guid } } ); msg.Add("eyeTrackerSerialNumber", SelectedTracker.SerialNumber); msg.Add("startTime", startTime); msg.Add("recordingCount", recordingCount); msg.Add("data", dataList); var settings = new JsonSerializerSettings(); var floatConverter = new StandardJsonConverter(); settings.Converters.Add(floatConverter); string jsonMSG = JsonConvert.SerializeObject(msg, settings); var message = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithPayload(jsonMSG) .WithExactlyOnceQoS() .WithRetainFlag(false) .Build(); await mqttClient.PublishAsync(message, CancellationToken.None); // Since 3.0.5 with CancellationToken dataList.Clear(); } } } catch (Exception exp) { //do nothing, skip Console.Write(exp); } } }); MQTTThread.Start(); if (StreamBtn.InvokeRequired) { StreamBtn.BeginInvoke((MethodInvoker) delegate() { this.StreamBtn.Text = "Stop"; }); } else { StreamBtn.Text = "Stop"; } } else { IsStreamingMQTT = false; SelectedTracker.GazeDataReceived -= HandleGazeData; if (StreamBtn.InvokeRequired) { StreamBtn.BeginInvoke((MethodInvoker) delegate() { this.StreamBtn.Text = "Stream"; }); } else { StreamBtn.Text = "Stream"; } MQTTThread.Join(); } }
async private void StreamBtn_Click(object sender, EventArgs e) { if (!IsStreamingToWAMP) { //maybe check if the connection before start wamp string CrossbarAddress = CrossbarIPTextBox.Text + "/ws"; string CrossbarRealm = RealmTextbox.Text; //This was the old code, might have to do some kind of hybrid depending on the url written. /*DefaultWampChannelFactory channelFactory = new DefaultWampChannelFactory(); * IWampChannel channel = channelFactory.CreateJsonChannel("wss://syn.ife.no/crossbarproxy/ws", CrossbarRealm); //CrossbarAddress * * channel.Open().Wait(); * //Task openTask = channel.Open() * //openTask.Wait(5000);*/ //if (CrossbarAddress.Contains("wss://")){ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //} WampChannelFactory factory = new WampChannelFactory(); IWampChannel channel = factory.ConnectToRealm(CrossbarRealm) .WebSocketTransport(new Uri(CrossbarAddress + "/ws")) .JsonSerialization() .Build(); IWampRealmProxy realmProxy = channel.RealmProxy; channel.RealmProxy.Monitor.ConnectionEstablished += (sender_inner, arg) => { Console.WriteLine("connected session with ID " + arg.SessionId); dynamic details = arg.WelcomeDetails.OriginalValue.Deserialize <dynamic>(); Console.WriteLine("authenticated using method '{0}' and provider '{1}'", details.authmethod, details.authprovider); Console.WriteLine("authenticated with authid '{0}' and authrole '{1}'", details.authid, details.authrole); }; channel.RealmProxy.Monitor.ConnectionBroken += (sender_inner, arg) => { dynamic details = arg.Details.OriginalValue.Deserialize <dynamic>(); Console.WriteLine("disconnected " + arg.Reason + " " + details.reason + details); Console.WriteLine("disconnected " + arg.Reason); }; await channel.Open().ConfigureAwait(false); WAMPSubject = realmProxy.Services.GetSubject("RETDataSample"); SelectedTracker.GazeDataReceived += HandleGazeData; IsStreamingToWAMP = true; WAMPThread = new Thread(() => { while (IsStreamingToWAMP) { try { while (GazeEventQueue.Any()) { GazeDataEventArgs gazeEvent; GazeEventQueue.TryDequeue(out gazeEvent); float gazeX = 0; float gazeY = 0; if (gazeEvent.LeftEye.GazePoint.Validity == Validity.Valid && gazeEvent.RightEye.GazePoint.Validity == Validity.Valid) { gazeX = (gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X + gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X) / 2; gazeY = (gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y + gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y) / 2; } else if (gazeEvent.LeftEye.GazePoint.Validity == Validity.Valid) { gazeX = gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X; gazeY = gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y; } else if (gazeEvent.RightEye.GazePoint.Validity == Validity.Valid) { gazeX = gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X; gazeY = gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y; } if (gazeEvent.LeftEye.Pupil.PupilDiameter != -1 || gazeEvent.RightEye.Pupil.PupilDiameter != -1) { CurrentPupilDiameters[0] = Double.IsNaN(gazeEvent.LeftEye.Pupil.PupilDiameter) ? -1 : gazeEvent.LeftEye.Pupil.PupilDiameter; CurrentPupilDiameters[1] = Double.IsNaN(gazeEvent.RightEye.Pupil.PupilDiameter) ? -1 : gazeEvent.RightEye.Pupil.PupilDiameter; } WampEvent evt = new WampEvent(); evt.Arguments = new object[] { SelectedTracker.SerialNumber, new object[] { CurrentPupilDiameters[0], gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X, gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y, CurrentPupilDiameters[1], gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X, gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y, gazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.X, gazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Y, gazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Z, gazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.X, gazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Y, gazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Z, gazeX, gazeY } }; WAMPSubject.OnNext(evt); } } catch (Exception exp) { //do nothing, skip Console.Write(exp); } } }); WAMPThread.Start(); if (StreamBtn.InvokeRequired) { StreamBtn.BeginInvoke((MethodInvoker) delegate() { this.StreamBtn.Text = "Stop"; }); } else { StreamBtn.Text = "Stop"; } } else { IsStreamingToWAMP = false; SelectedTracker.GazeDataReceived -= HandleGazeData; if (StreamBtn.InvokeRequired) { StreamBtn.BeginInvoke((MethodInvoker) delegate() { this.StreamBtn.Text = "Stream"; }); } else { StreamBtn.Text = "Stream"; } WAMPThread.Join(); } }