c++ - How to wait for WebSocket response in PNaCl -


i'm implementing "wait websocket response before continuation" mechanism on pnacl plugin through pp::websocketapi in ppapi. following simplified version stores replied data global std::string, while function myecho() sends string through websocket , polling until global string changes. driver web page same in websocket example in nacl sdk.

#include <string> #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" #include "ppapi/cpp/var.h" #include "ppapi/cpp/var_array_buffer.h" #include "ppapi/utility/websocket/websocket_api.h"  class mywebsocketreceivelistener { public:     virtual void onwebsocketdatareceived(const std::string& data) = 0; };  class mywebsocketapi : protected pp::websocketapi { public:     mywebsocketapi(pp::instance* ppinstance, mywebsocketreceivelistener* recvlistener)         : pp::websocketapi(ppinstance), m_onreceivelistener(recvlistener), m_ppinstance(ppinstance) {}     virtual ~mywebsocketapi() {}      bool isconnected() { return pp::websocketapi::getreadystate() == pp_websocketreadystate_open; }     void open(const std::string& url) { pp::websocketapi::connect(url, null, 0); }     void close() { pp::websocketapi::close(pp_websocketstatuscode_normal_closure, "bye"); }     void senddata(const std::string& data) { pp::websocketapi::send(data); }  protected:     virtual void websocketdidopen() { m_ppinstance->postmessage("connected"); }     virtual void websocketdidclose(bool wasclean, uint16_t code, const pp::var& reason) {}     virtual void handlewebsocketmessage(const pp::var& message)     {         if (message.is_array_buffer()) {             pp::vararraybuffer vararybuf(message);             char *data = static_cast<char*>(vararybuf.map());             std::string datastr(data, data + vararybuf.bytelength());             vararybuf.unmap();             m_onreceivelistener->onwebsocketdatareceived(datastr);         } else { // string             m_onreceivelistener->onwebsocketdatareceived(message.asstring());         }     }     virtual void handlewebsocketerror() {} private:     mywebsocketapi(const mywebsocketapi&);     mywebsocketapi& operator=(const mywebsocketapi&);      mywebsocketreceivelistener* const m_onreceivelistener;     pp::instance * const m_ppinstance; };  static std::string g_returnval;  class myppplugininstance : public pp::instance, public mywebsocketreceivelistener { public:     explicit myppplugininstance(pp_instance instance)         : pp::instance(instance), rpcwebsocket_(this, this) {}     virtual ~myppplugininstance() {}     virtual void handlemessage(const pp::var& var_message);     virtual void onwebsocketdatareceived(const std::string& data)     {         g_returnval = data;     }  private:     bool isconnected() { return rpcwebsocket_.isconnected(); }     void open(const std::string& url)     {         rpcwebsocket_.open(url);         postmessage(pp::var("connecting..."));     }     void close()     {         if (!isconnected())             return;         rpcwebsocket_.close();     }      mywebsocketapi rpcwebsocket_; };  std::string myecho(pp::instance* inst, mywebsocketapi& ws, const std::string& in) {     ws.senddata(in);     while (g_returnval.empty()) {         usleep(1000 * 1000); // 1 sec         inst->postmessage("waiting response...");     }     return g_returnval; }  void myppplugininstance::handlemessage(const pp::var& var_message) {     if (!var_message.is_string())         return;     std::string message = var_message.asstring();     // message must contain command character followed ';' ,     // arguments "x;arguments".     if (message.length() < 2 || message[1] != ';')         return;     switch (message[0]) {     case 'o':         // command 'o' requests open specified url.         // url passed argument "o;url".         open(message.substr(2));         break;     case 'c':         // command 'c' requests close without argument "c;"         close();         break;     case 'b':     case 't':         postmessage(std::string("calling remote echo ") + message.substr(2));         std::string ret(myecho(this, rpcwebsocket_, message.substr(2)));         postmessage(ret);         break;     } }  // creates myppplugininstance objects when invoked. class mypppluginmodule : public pp::module { public:     mypppluginmodule() : pp::module() {}     virtual ~mypppluginmodule() {}      virtual pp::instance* createinstance(pp_instance instance) {         return new myppplugininstance(instance);     } };  // implement required pp::createmodule function creates our specific // kind of module. namespace pp {     module* createmodule() { return new mypppluginmodule(); } }  // namespace pp 

however, approach didn't work. after connecting echo test server ws://echo.websocket.org , send "hello", get

connecting... connected calling remote echo hello waiting response... waiting response... waiting response... waiting response... waiting response... 

(never replies)

i used hand-crafted websocket server test, , message sent server successfully. , in addition usleep() polling in attached snippet, i've tried use pthread_cond_wait() , pthread_cond_signal() wait , notify received message.

what should "wait pp::websocketapi receive data" correctly?

the function myecho() blocks myppplugininstance::handlemessage() , somehow in turn blocks receiving websocket.

i added pp::simplethread new data member of class myppplugininstance , dispatch myecho() thread through pp::simplethread::message_loop().postwork(). works smoothly.


Comments

Popular posts from this blog

node.js - Using Node without global install -

How to access a php class file from PHPFox framework into javascript code written in simple HTML file? -

java - Null response to php query in android, even though php works properly -