fixed communication issues with the base station caused by data distributed over multiple packets once and for all (hopefully)
This commit is contained in:
parent
a0a3d8cfe6
commit
75b193e642
7 changed files with 175 additions and 41 deletions
|
@ -96,8 +96,12 @@ public slots:
|
|||
|
||||
void gotError(QAbstractSocket::SocketError err);
|
||||
|
||||
// --- socket communication handling ---
|
||||
|
||||
Q_INVOKABLE QVariantMap sendCommand(int header, QJsonValue data = "");
|
||||
|
||||
// --- helper functions ---
|
||||
|
||||
Q_INVOKABLE int writeRemoteSetting(QString key, QString value);
|
||||
|
||||
Q_INVOKABLE bool refreshConnections();
|
||||
|
@ -116,6 +120,10 @@ public slots:
|
|||
private slots:
|
||||
void readyRead();
|
||||
|
||||
void processSocketMessage(QString message);
|
||||
|
||||
void socketReplyRecieved(QString reply);
|
||||
|
||||
void socketStateChanged(QAbstractSocket::SocketState socketState);
|
||||
};
|
||||
extern BaseConn * pGlobalBaseConn;
|
||||
|
|
|
@ -131,7 +131,7 @@ Popup {
|
|||
|
||||
loadData: function () {
|
||||
status = 905
|
||||
listData = {}
|
||||
//listData = {}
|
||||
var retData = speedBackend.getAthletes()
|
||||
|
||||
if(retData === undefined){
|
||||
|
@ -151,8 +151,7 @@ Popup {
|
|||
|
||||
text: profileList.listData[index]["fullName"]
|
||||
width: profileList.width - (swipeDelegate.x)
|
||||
|
||||
|
||||
height: profileList.height / 5
|
||||
|
||||
font.pixelSize: profiles_stack.text_pixelSize
|
||||
|
||||
|
@ -164,8 +163,35 @@ Popup {
|
|||
profiles_stack.openResults(profileList.listData[index]["userName"])
|
||||
}
|
||||
|
||||
contentItem: Text {
|
||||
visible: false
|
||||
}
|
||||
|
||||
Text {
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: swipeDelegate.width * 0.05
|
||||
right: parent.right
|
||||
rightMargin: swipeDelegate.rightPadding
|
||||
}
|
||||
|
||||
text: swipeDelegate.text
|
||||
color: appTheme.style.textColor
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
|
||||
font.pixelSize: swipeDelegate.height * 0.4
|
||||
|
||||
minimumPixelSize: 1
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: Qt.darker( pressed ? Qt.darker("white", 1.1):"white", swipeDelegate.active ? 1.1:0 )
|
||||
color: pressed ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
|
||||
|
||||
Behavior on color {
|
||||
|
||||
|
@ -205,6 +231,7 @@ Popup {
|
|||
|
||||
radius: width * 0.2
|
||||
border.color: control.down ? "#17a81a" : "#21be2b"
|
||||
color: control.down ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
|
||||
|
||||
Rectangle {
|
||||
width: parent.width * 0.65
|
||||
|
@ -273,7 +300,7 @@ Popup {
|
|||
Label {
|
||||
id: deleteLabel
|
||||
text: qsTr("Delete")
|
||||
color: "white"
|
||||
color: appTheme.style.textColor
|
||||
verticalAlignment: Label.AlignVCenter
|
||||
padding: 12
|
||||
height: parent.height
|
||||
|
@ -353,6 +380,7 @@ Popup {
|
|||
|
||||
signal opened()
|
||||
|
||||
|
||||
onOpened: {
|
||||
loadData()
|
||||
}
|
||||
|
@ -364,14 +392,18 @@ Popup {
|
|||
status = listData.lenght !== false ? 200:0
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
delegate: SmoothItemDelegate {
|
||||
id: resultDel
|
||||
|
||||
width: parent.width
|
||||
height: resultView.height / 4
|
||||
|
||||
font.pixelSize: profiles_stack.text_pixelSize
|
||||
backgroundRect.radius: 0
|
||||
|
||||
text: "result: " + (listData[index]["result"] / 1000).toFixed(3) + " sec \nreaction time: " + listData[index]["reactionTime"].toFixed(0) + " ms"
|
||||
function getDateText(){
|
||||
var date = new Date(listData[index]["timestamp"]*1000).toLocaleString(Qt.locale(), "dddd, dd.MMM HH:mm")
|
||||
return date
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: "grey"
|
||||
|
@ -384,18 +416,47 @@ Popup {
|
|||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: parent.width * 0.05
|
||||
|
||||
font.pixelSize: 10
|
||||
Label {
|
||||
id: dateLa
|
||||
|
||||
text: " " + getText()
|
||||
height: parent.height / parent.children.length
|
||||
|
||||
function getText(){
|
||||
var date = new Date(listData[index]["timestamp"]*1000).toLocaleDateString(Qt.locale("de_DE"))
|
||||
return date
|
||||
console.log(date)
|
||||
font.pixelSize: height * 0.8
|
||||
fontSizeMode: Text.Fit
|
||||
|
||||
color: appTheme.style.textColor
|
||||
|
||||
text: resultDel.getDateText()
|
||||
}
|
||||
|
||||
Label {
|
||||
id: resultLa
|
||||
|
||||
height: parent.height / parent.children.length
|
||||
|
||||
font.pixelSize: height * 0.8
|
||||
fontSizeMode: Text.Fit
|
||||
|
||||
color: appTheme.style.textColor
|
||||
|
||||
text: qsTr("result: ") + (listData[index]["result"] / 1000).toFixed(3) + " s"
|
||||
}
|
||||
|
||||
Label {
|
||||
id: reactionTimeLa
|
||||
|
||||
height: parent.height / parent.children.length
|
||||
|
||||
font.pixelSize: height * 0.8
|
||||
fontSizeMode: Text.Fit
|
||||
|
||||
color: appTheme.style.textColor
|
||||
|
||||
text: qsTr("reaction time: ") + listData[index]["reactionTime"].toFixed(0) + " ms"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -548,6 +609,8 @@ Popup {
|
|||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
color: appTheme.style.textColor
|
||||
|
||||
text: profiles_stack.currentItem.title
|
||||
|
||||
}
|
||||
|
@ -611,6 +674,9 @@ Popup {
|
|||
leftMargin: parent.width/2 - width/2
|
||||
}
|
||||
opacity: profiles_stack.currentItem.secondButt === "add" ? 1:0
|
||||
|
||||
color: appTheme.style.textColor
|
||||
|
||||
text: "+"
|
||||
font.pixelSize: parent.height
|
||||
}
|
||||
|
|
|
@ -192,7 +192,6 @@ Popup {
|
|||
|
||||
glowOpacity: Math.pow( root.opacity, 100 )
|
||||
|
||||
backgroundColor: appTheme.style.buttonColor
|
||||
image: appTheme.style.backIcon
|
||||
|
||||
onClicked: {
|
||||
|
|
|
@ -6,7 +6,7 @@ Button {
|
|||
id: control
|
||||
|
||||
property string image
|
||||
property color backgroundColor: "white"
|
||||
property color backgroundColor: appTheme.style.buttonColor
|
||||
property real imageScale: 1
|
||||
property double glowRadius: 0.001
|
||||
property double glowSpread: 0.2
|
||||
|
@ -16,7 +16,7 @@ Button {
|
|||
|
||||
|
||||
|
||||
scale: control.pressed ? 0.8:1
|
||||
//scale: control.pressed ? 0.8:1
|
||||
|
||||
Behavior on scale {
|
||||
PropertyAnimation {
|
||||
|
@ -24,12 +24,6 @@ Button {
|
|||
}
|
||||
}
|
||||
|
||||
Behavior on backgroundColor {
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
background: Item {
|
||||
id: controlBackgroundContainer
|
||||
|
||||
|
@ -48,13 +42,19 @@ Button {
|
|||
}
|
||||
|
||||
Rectangle {
|
||||
id: controlBackground
|
||||
id: controlBackground
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
radius: height * 0.5
|
||||
|
||||
color: control.backgroundColor
|
||||
color: control.down ? Qt.darker(control.backgroundColor, 1.2) : control.backgroundColor
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: buttonIcon
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import QtQuick 2.9
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.4
|
||||
|
||||
Item {
|
||||
|
@ -7,6 +7,7 @@ Item {
|
|||
property var loadData
|
||||
property var listData: ({})
|
||||
property Component delegate
|
||||
property alias view: listView
|
||||
|
||||
property int status: -1
|
||||
|
||||
|
@ -23,11 +24,12 @@ Item {
|
|||
|
||||
anchors.fill: parent
|
||||
|
||||
boundsBehavior: Flickable.DragOverBounds
|
||||
boundsMovement: Flickable.StopAtBounds
|
||||
|
||||
//enabled: status === 200 || status === 902
|
||||
//opacity: enabled ? 1:0
|
||||
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
parent: listView.parent
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ import QtQuick.Controls 2.2
|
|||
ItemDelegate {
|
||||
id: control
|
||||
text: ""
|
||||
font.pixelSize: options_stack.text_pixelSize
|
||||
property color textColor: appTheme.style.textColor
|
||||
property alias backgroundRect: backgroundRect
|
||||
|
||||
opacity: enabled ? 1 : 0.2
|
||||
|
||||
|
@ -26,16 +26,20 @@ ItemDelegate {
|
|||
text: control.text
|
||||
color: appTheme.style.textColor
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
|
||||
font.pixelSize: control.height * 0.4
|
||||
|
||||
minimumPixelSize: 0
|
||||
minimumPixelSize: 1
|
||||
}
|
||||
|
||||
width: parent.width
|
||||
|
||||
background: Rectangle {
|
||||
id: backgroundRect
|
||||
color: control.down ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
|
||||
|
||||
radius: height * 0.3
|
||||
|
|
|
@ -122,6 +122,10 @@ void BaseConn::gotError(QAbstractSocket::SocketError err)
|
|||
qDebug() << "got socket error: " << strError;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
// --- socket communication handling ---
|
||||
// -------------------------------------
|
||||
|
||||
QVariantMap BaseConn::sendCommand(int header, QJsonValue data){
|
||||
if(this->state != "connected"){
|
||||
return {{"status", 910}, {"data", "not connected"}};
|
||||
|
@ -178,8 +182,6 @@ QVariantMap BaseConn::sendCommand(int header, QJsonValue data){
|
|||
// stop the timer as the connection has been established
|
||||
timer.stop();
|
||||
|
||||
timer.deleteLater();
|
||||
|
||||
return {{"status", reply.value("header").toInt()}, {"data", reply.value("data").toVariant()}};
|
||||
|
||||
}
|
||||
|
@ -189,17 +191,64 @@ void BaseConn::readyRead() {
|
|||
//qDebug() << "ready to ready " << socket->bytesAvailable() << " bytes" ;
|
||||
QString reply = socket->readAll();
|
||||
|
||||
if(!reply.endsWith("</message>")){
|
||||
this->readBuffer += reply;
|
||||
//qWarning() << "socket read: " << reply;
|
||||
|
||||
processSocketMessage(reply);
|
||||
}
|
||||
|
||||
void BaseConn::processSocketMessage(QString message){
|
||||
QString startKey = "<message>";
|
||||
QString endKey = "</message>";
|
||||
|
||||
//qWarning() << "... processing message now ... : " << message;
|
||||
|
||||
if(message == ""){
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
if((message.startsWith(startKey) && message.endsWith(endKey)) && (message.count(startKey) == 1 && message.count(endKey) == 1)){
|
||||
// non-split message ( e.g.: <message>123456789</message>
|
||||
}
|
||||
else if(!message.contains(endKey) && (!this->readBuffer.isEmpty() || message.startsWith(startKey))){
|
||||
// begin of a split message ( e.g.: <message>123 )
|
||||
// or middle of a split message ( e.g.: 456 )
|
||||
//qWarning() << "this is a begin or middle of split a message";
|
||||
this->readBuffer += message;
|
||||
return;
|
||||
}
|
||||
else if(!message.contains(startKey) && message.endsWith(endKey)) {
|
||||
// end of a split message ( e.g.: 789</message> )
|
||||
|
||||
if(!this->readBuffer.isEmpty()){
|
||||
reply = readBuffer + reply;
|
||||
message = readBuffer + message;
|
||||
readBuffer.clear();
|
||||
}
|
||||
}
|
||||
else if((message.count(startKey) > 1 || message.count(endKey) > 1) || (message.contains(endKey) && !message.endsWith(endKey) && message.contains(startKey) && !message.startsWith(startKey))) {
|
||||
// multiple messages in one packet ( e.g.: <message>123456789</message><message>987654321</message> )
|
||||
// or multiple message fragments in one message ( e.g.: 56789</message><message>987654321</message> or 56789</message><message>98765 )
|
||||
//qDebug() << "detected multiple messages";
|
||||
|
||||
int startOfSecondMessage = message.lastIndexOf(startKey);
|
||||
// process first part of message
|
||||
QString firstMessage = message.left(startOfSecondMessage);
|
||||
this->processSocketMessage(firstMessage);
|
||||
// process second part of message
|
||||
QString secondMessage = message.right(message.length() - startOfSecondMessage);
|
||||
this->processSocketMessage(secondMessage);
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// invalid message
|
||||
return;
|
||||
}
|
||||
|
||||
//qWarning() << "... done processing, message: " << message;
|
||||
this->socketReplyRecieved(message);
|
||||
}
|
||||
|
||||
void BaseConn::socketReplyRecieved(QString reply) {
|
||||
reply.replace("<message>", "");
|
||||
reply.replace("</message>", "");
|
||||
|
||||
|
@ -216,7 +265,9 @@ void BaseConn::readyRead() {
|
|||
for(int i = 0; i < this->waitingRequests.length(); i++){
|
||||
if(this->waitingRequests[i].id == id){
|
||||
this->waitingRequests[i].reply = replyObj;
|
||||
this->waitingRequests[i].loop->quit();
|
||||
if(this->waitingRequests[i].loop != nullptr){
|
||||
this->waitingRequests[i].loop->quit();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -224,9 +275,12 @@ void BaseConn::readyRead() {
|
|||
|
||||
latestReadReply = reply;
|
||||
emit gotUnexpectedReply(reply);
|
||||
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// --- helper functions ---
|
||||
// ------------------------
|
||||
|
||||
int BaseConn::writeRemoteSetting(QString key, QString value) {
|
||||
QJsonArray requestData;
|
||||
requestData.append(key);
|
||||
|
@ -257,6 +311,7 @@ void BaseConn::socketStateChanged(QAbstractSocket::SocketState socketState) {
|
|||
switch (socketState) {
|
||||
case QAbstractSocket::UnconnectedState:
|
||||
{
|
||||
this->deInit();
|
||||
this->setState("disconnected");
|
||||
break;
|
||||
}
|
||||
|
|
Reference in a new issue