Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] QWebSocketServer: strange behaviour
QtWS25 Last Chance

[SOLVED] QWebSocketServer: strange behaviour

Scheduled Pinned Locked Moved General and Desktop
qwebsocketservemsvc13g++
2 Posts 1 Posters 1.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sirop
    wrote on 18 Oct 2015, 11:14 last edited by sirop
    #1

    Hallo.

    I have derived my Websocket server from the example http://doc.qt.io/qt-5/qtwebsockets-simplechat-example.html .

    However, I see some strange behaviour:

    • the user authenticates himself with an auth message
    • this message is parsed correctly
    • then the user sends his first normal message to the chat
    • this first normal message can not be parsed as the previous auth message is prepended to this normal message
    • the debug output of the first chat message arriving at the server is:
    "{"action":"auth","data":{"username":"testchat1","password":"test1"}}{"action":"msg","data":{"channelid":"3","msg":"message testchat1"}}"
     WebSocket Server Error:  ""
    

    As you see, the auth message is prepended to the "normal" message as if it were buffered on the chat server. I tried to intercept any WebSocket Server Error with m_pWebSocketServer->errorString() , but there seems to be no error.
    This happens only once, the next chat message is parsed correctly and nothing is prepended to it.
    My executable is compiled with msvc13 and runs under Win 8.

    Things get worse if I move to Ubuntu and compile with g++ 4.9.1. Then it seems that the auth message is always bufffered and a normal message is never processed/parsed as only the unintentionally buffered auth message is parsed each time I send a "normal" chat message.

    Because of this difference between OS and compilers I do think the reason lies within Qt and not on the client side which is a simple javacript client.

    Just to give you some idea of my code:

    void ChatServer::onNewConnection()
    {
        QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
    
        connect(pSocket, &QWebSocket::textMessageReceived, this, &ChatServer::processJsonString);
        connect(pSocket, &QWebSocket::disconnected, this, &ChatServer::socketDisconnected);
    
       m_clients << pSocket;
    }
    
    
    void ChatServer::processJsonString(const QString &jsonstring)
    {
        qDebug()<<"processJsonString called";
    
        QWebSocket *pSender = qobject_cast<QWebSocket*>(sender());
        QJsonObject dataObject = QJsonDocument::fromJson(jsonstring.toUtf8()).object();
    
    
     //switch (dataObject.value("action").toString()[0].toLatin1()){
    
    
       // case 'a':
        if (dataObject.value("action").toString()=="auth")
        {
            qDebug()<< "auth";
            QString password=dataObject.value("data").toObject().value("password").toString();
            QString username=dataObject.value("data").toObject().value("username").toString();
            //quint64 userID=dataObject.value("data").toObject().value("userID").toInt();
            qDebug()<<"password: " << password;
            qDebug()<<"username: " <<username;
            //qDebug()<<"userID: " <<userID;
    
            rc=new RestConn(username , password, apiToken, baseUrl, pSender);
        
           connect(rc,&RestConn::gotAuthJSONReply, this, &ChatServer::processAUTH);
            rc->sendRequest();
      
            return;
        }
    
    
     // case 'm':
        if (dataObject.value("action").toString()=="msg")
        {
           // qDebug()<< "msg: " << dataObject.value("data").toString()<< "channelid: " <<dataObject.value("channelid").toInt();
          qDebug()<< "msg: "  << jsonstring ; //<< "\n";
            quint64 userID=userWebsockets->value(pSender, 0); // 0 is SYSTEM's userID
           quint64 channelID=dataObject.value("data").toObject().value("channelid").toString().toInt();
             qDebug()<< "msg: channelid: "  <<channelID ; // << "\n";
            QString message=dataObject.value("data").toObject().value("msg").toString();
            qDebug()<< "msg: message: "  << message<< "\n";
            QString serverTime= QDateTime::currentDateTime().toString(Qt::ISODate);  // check if ISO or compliant to Postgres date/time types
           // incmsg
            if (channels->value(channelID, NULL)==NULL) // ?????????
               {
                 pSender->sendTextMessage("{ action: 'msg',status: 'error', data: {id: '2', msg: 'Request parse error'} }" );
                 return;
               }
        
            pSender->sendTextMessage("{ action: 'msg',status: 'ok',data: {} }" );
    
    //        //json_object('{senderID, author, receiverID, message, channel, time}'
    //        // remove receiverID, leave only channel ID  !!!!!!!!
    
            messageCounter++;
            QString stringToInsert=QString::number(userID) % "," % QString::number(messageCounter)% ","  % message % ","
                    % QString::number(channelID) % "," % serverTime;
    
    
            steadyBulkInsert->writeJsonValues(stringToInsert);
    
           // break;
            return;
    
         }
         }
       else
       {
         qDebug()<< jsonstring<<"\n" <<"WebSocket Server Error: " << m_pWebSocketServer->errorString() << "\n";
        }
    
     return;
    }
    
    

    So what is this? A bug?

    To be, or not to be: that is the question:
    Whether ’tis nobler in the mind to suffer
    The slings and arrows of outrageous fortune,
    Or to take arms against a sea of troubles,
    And by opposing end them?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      sirop
      wrote on 18 Oct 2015, 16:05 last edited by
      #2

      Ok, just solved it through trial and error.

      Had a messy QEventLoop and another place, which, however, was used during auth parsing.
      Now it looks like this:

       QNetworkAccessManager nam;
              QEventLoop loop;     
              connect(&nam, &QNetworkAccessManager::finished, this, &RestConn::processReply);
               nam.get(*request);
               loop.connect(&nam, SIGNAL(finished(QNetworkReply*)),&loop, SLOT(quit()));
               loop.exec(QEventLoop::AllEvents);
      

      And before - in the error case - the last two lines did not follow in correct order as they were:

      // This order is not correct
       loop.exec(QEventLoop::AllEvents);
       loop.connect(&nam, SIGNAL(finished(QNetworkReply*)),&loop, SLOT(quit()));
      

      Thanks to all anyway.

      To be, or not to be: that is the question:
      Whether ’tis nobler in the mind to suffer
      The slings and arrows of outrageous fortune,
      Or to take arms against a sea of troubles,
      And by opposing end them?

      1 Reply Last reply
      0

      1/2

      18 Oct 2015, 11:14

      • Login

      • Login or register to search.
      1 out of 2
      • First post
        1/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved