mirror of https://github.com/axmolengine/axmol.git
Merge pull request #5939 from dumganhar/merge5923
Merge PR #5923: implement fireEventToScript method to integrate JSB event handling with the original native code
This commit is contained in:
commit
ec4b1ee485
|
@ -1,19 +1,19 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Copyright (c) 2013 Chris Hannon
|
Copyright (c) 2013 Chris Hannon
|
||||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||||
|
|
||||||
http://www.cocos2d-x.org
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
@ -43,114 +43,114 @@ namespace network {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The implementation of the socket.io connection
|
* @brief The implementation of the socket.io connection
|
||||||
* Clients/endpoints may share the same impl to accomplish multiplexing on the same websocket
|
* Clients/endpoints may share the same impl to accomplish multiplexing on the same websocket
|
||||||
*/
|
*/
|
||||||
class SIOClientImpl :
|
class SIOClientImpl :
|
||||||
public cocos2d::Ref,
|
public cocos2d::Ref,
|
||||||
public WebSocket::Delegate
|
public WebSocket::Delegate
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int _port, _heartbeat, _timeout;
|
int _port, _heartbeat, _timeout;
|
||||||
std::string _host, _sid, _uri;
|
std::string _host, _sid, _uri;
|
||||||
bool _connected;
|
bool _connected;
|
||||||
|
|
||||||
WebSocket *_ws;
|
WebSocket *_ws;
|
||||||
|
|
||||||
Map<std::string, SIOClient*> _clients;
|
Map<std::string, SIOClient*> _clients;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SIOClientImpl(const std::string& host, int port);
|
SIOClientImpl(const std::string& host, int port);
|
||||||
virtual ~SIOClientImpl(void);
|
virtual ~SIOClientImpl(void);
|
||||||
|
|
||||||
static SIOClientImpl* create(const std::string& host, int port);
|
static SIOClientImpl* create(const std::string& host, int port);
|
||||||
|
|
||||||
virtual void onOpen(WebSocket* ws);
|
virtual void onOpen(WebSocket* ws);
|
||||||
virtual void onMessage(WebSocket* ws, const WebSocket::Data& data);
|
virtual void onMessage(WebSocket* ws, const WebSocket::Data& data);
|
||||||
virtual void onClose(WebSocket* ws);
|
virtual void onClose(WebSocket* ws);
|
||||||
virtual void onError(WebSocket* ws, const WebSocket::ErrorCode& error);
|
virtual void onError(WebSocket* ws, const WebSocket::ErrorCode& error);
|
||||||
|
|
||||||
void connect();
|
void connect();
|
||||||
void disconnect();
|
void disconnect();
|
||||||
bool init();
|
bool init();
|
||||||
void handshake();
|
void handshake();
|
||||||
void handshakeResponse(HttpClient *sender, HttpResponse *response);
|
void handshakeResponse(HttpClient *sender, HttpResponse *response);
|
||||||
void openSocket();
|
void openSocket();
|
||||||
void heartbeat(float dt);
|
void heartbeat(float dt);
|
||||||
|
|
||||||
SIOClient* getClient(const std::string& endpoint);
|
SIOClient* getClient(const std::string& endpoint);
|
||||||
void addClient(const std::string& endpoint, SIOClient* client);
|
void addClient(const std::string& endpoint, SIOClient* client);
|
||||||
|
|
||||||
void connectToEndpoint(const std::string& endpoint);
|
|
||||||
void disconnectFromEndpoint(const std::string& endpoint);
|
|
||||||
|
|
||||||
void send(std::string endpoint, std::string s);
|
void connectToEndpoint(const std::string& endpoint);
|
||||||
void emit(std::string endpoint, std::string eventname, std::string args);
|
void disconnectFromEndpoint(const std::string& endpoint);
|
||||||
|
|
||||||
|
void send(std::string endpoint, std::string s);
|
||||||
|
void emit(std::string endpoint, std::string eventname, std::string args);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//method implementations
|
//method implementations
|
||||||
|
|
||||||
//begin SIOClientImpl methods
|
//begin SIOClientImpl methods
|
||||||
SIOClientImpl::SIOClientImpl(const std::string& host, int port) :
|
SIOClientImpl::SIOClientImpl(const std::string& host, int port) :
|
||||||
_port(port),
|
_port(port),
|
||||||
_host(host),
|
_host(host),
|
||||||
_connected(false)
|
_connected(false)
|
||||||
{
|
{
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << host << ":" << port;
|
s << host << ":" << port;
|
||||||
_uri = s.str();
|
_uri = s.str();
|
||||||
|
|
||||||
_ws = nullptr;
|
_ws = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIOClientImpl::~SIOClientImpl()
|
SIOClientImpl::~SIOClientImpl()
|
||||||
{
|
{
|
||||||
if (_connected)
|
if (_connected)
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|
||||||
CC_SAFE_DELETE(_ws);
|
CC_SAFE_DELETE(_ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::handshake()
|
void SIOClientImpl::handshake()
|
||||||
{
|
{
|
||||||
log("SIOClientImpl::handshake() called");
|
log("SIOClientImpl::handshake() called");
|
||||||
|
|
||||||
std::stringstream pre;
|
std::stringstream pre;
|
||||||
pre << "http://" << _uri << "/socket.io/1";
|
pre << "http://" << _uri << "/socket.io/1";
|
||||||
|
|
||||||
HttpRequest* request = new HttpRequest();
|
HttpRequest* request = new HttpRequest();
|
||||||
request->setUrl(pre.str().c_str());
|
request->setUrl(pre.str().c_str());
|
||||||
request->setRequestType(HttpRequest::Type::GET);
|
request->setRequestType(HttpRequest::Type::GET);
|
||||||
|
|
||||||
request->setResponseCallback(this, httpresponse_selector(SIOClientImpl::handshakeResponse));
|
request->setResponseCallback(this, httpresponse_selector(SIOClientImpl::handshakeResponse));
|
||||||
request->setTag("handshake");
|
request->setTag("handshake");
|
||||||
|
|
||||||
log("SIOClientImpl::handshake() waiting");
|
log("SIOClientImpl::handshake() waiting");
|
||||||
|
|
||||||
HttpClient::getInstance()->send(request);
|
HttpClient::getInstance()->send(request);
|
||||||
|
|
||||||
request->release();
|
request->release();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::handshakeResponse(HttpClient *sender, HttpResponse *response)
|
void SIOClientImpl::handshakeResponse(HttpClient *sender, HttpResponse *response)
|
||||||
{
|
{
|
||||||
log("SIOClientImpl::handshakeResponse() called");
|
log("SIOClientImpl::handshakeResponse() called");
|
||||||
|
|
||||||
if (0 != strlen(response->getHttpRequest()->getTag()))
|
if (0 != strlen(response->getHttpRequest()->getTag()))
|
||||||
{
|
{
|
||||||
log("%s completed", response->getHttpRequest()->getTag());
|
log("%s completed", response->getHttpRequest()->getTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
long statusCode = response->getResponseCode();
|
long statusCode = response->getResponseCode();
|
||||||
char statusString[64] = {};
|
char statusString[64] = {};
|
||||||
sprintf(statusString, "HTTP Status Code: %ld, tag = %s", statusCode, response->getHttpRequest()->getTag());
|
sprintf(statusString, "HTTP Status Code: %ld, tag = %s", statusCode, response->getHttpRequest()->getTag());
|
||||||
log("response code: %ld", statusCode);
|
log("response code: %ld", statusCode);
|
||||||
|
|
||||||
if (!response->isSucceed())
|
if (!response->isSucceed())
|
||||||
{
|
{
|
||||||
log("SIOClientImpl::handshake() failed");
|
log("SIOClientImpl::handshake() failed");
|
||||||
log("error buffer: %s", response->getErrorBuffer());
|
log("error buffer: %s", response->getErrorBuffer());
|
||||||
|
@ -163,302 +163,302 @@ void SIOClientImpl::handshakeResponse(HttpClient *sender, HttpResponse *response
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log("SIOClientImpl::handshake() succeeded");
|
log("SIOClientImpl::handshake() succeeded");
|
||||||
|
|
||||||
std::vector<char> *buffer = response->getResponseData();
|
std::vector<char> *buffer = response->getResponseData();
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < buffer->size(); i++)
|
for (unsigned int i = 0; i < buffer->size(); i++)
|
||||||
{
|
{
|
||||||
s << (*buffer)[i];
|
s << (*buffer)[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
log("SIOClientImpl::handshake() dump data: %s", s.str().c_str());
|
|
||||||
|
|
||||||
std::string res = s.str();
|
log("SIOClientImpl::handshake() dump data: %s", s.str().c_str());
|
||||||
std::string sid;
|
|
||||||
size_t pos = 0;
|
|
||||||
int heartbeat = 0, timeout = 0;
|
|
||||||
|
|
||||||
pos = res.find(":");
|
std::string res = s.str();
|
||||||
if(pos != std::string::npos)
|
std::string sid;
|
||||||
|
size_t pos = 0;
|
||||||
|
int heartbeat = 0, timeout = 0;
|
||||||
|
|
||||||
|
pos = res.find(":");
|
||||||
|
if(pos != std::string::npos)
|
||||||
{
|
{
|
||||||
sid = res.substr(0, pos);
|
sid = res.substr(0, pos);
|
||||||
res.erase(0, pos+1);
|
res.erase(0, pos+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = res.find(":");
|
pos = res.find(":");
|
||||||
if(pos != std::string::npos)
|
if(pos != std::string::npos)
|
||||||
{
|
{
|
||||||
heartbeat = atoi(res.substr(pos+1, res.size()).c_str());
|
heartbeat = atoi(res.substr(pos+1, res.size()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = res.find(":");
|
pos = res.find(":");
|
||||||
if(pos != std::string::npos)
|
if(pos != std::string::npos)
|
||||||
{
|
{
|
||||||
timeout = atoi(res.substr(pos+1, res.size()).c_str());
|
timeout = atoi(res.substr(pos+1, res.size()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
_sid = sid;
|
_sid = sid;
|
||||||
_heartbeat = heartbeat;
|
_heartbeat = heartbeat;
|
||||||
_timeout = timeout;
|
_timeout = timeout;
|
||||||
|
|
||||||
openSocket();
|
|
||||||
|
|
||||||
return;
|
openSocket();
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::openSocket()
|
void SIOClientImpl::openSocket()
|
||||||
{
|
{
|
||||||
log("SIOClientImpl::openSocket() called");
|
log("SIOClientImpl::openSocket() called");
|
||||||
|
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << _uri << "/socket.io/1/websocket/" << _sid;
|
s << _uri << "/socket.io/1/websocket/" << _sid;
|
||||||
|
|
||||||
_ws = new WebSocket();
|
_ws = new WebSocket();
|
||||||
if (!_ws->init(*this, s.str()))
|
if (!_ws->init(*this, s.str()))
|
||||||
{
|
{
|
||||||
CC_SAFE_DELETE(_ws);
|
CC_SAFE_DELETE(_ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SIOClientImpl::init()
|
bool SIOClientImpl::init()
|
||||||
{
|
{
|
||||||
log("SIOClientImpl::init() successful");
|
log("SIOClientImpl::init() successful");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::connect()
|
void SIOClientImpl::connect()
|
||||||
{
|
{
|
||||||
this->handshake();
|
this->handshake();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::disconnect()
|
void SIOClientImpl::disconnect()
|
||||||
{
|
{
|
||||||
if(_ws->getReadyState() == WebSocket::State::OPEN)
|
if(_ws->getReadyState() == WebSocket::State::OPEN)
|
||||||
{
|
{
|
||||||
std::string s = "0::";
|
std::string s = "0::";
|
||||||
|
|
||||||
_ws->send(s);
|
_ws->send(s);
|
||||||
|
|
||||||
log("Disconnect sent");
|
log("Disconnect sent");
|
||||||
|
|
||||||
_ws->close();
|
_ws->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Director::getInstance()->getScheduler()->unscheduleAllForTarget(this);
|
Director::getInstance()->getScheduler()->unscheduleAllForTarget(this);
|
||||||
|
|
||||||
_connected = false;
|
_connected = false;
|
||||||
|
|
||||||
SocketIO::getInstance()->removeSocket(_uri);
|
SocketIO::getInstance()->removeSocket(_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIOClientImpl* SIOClientImpl::create(const std::string& host, int port)
|
SIOClientImpl* SIOClientImpl::create(const std::string& host, int port)
|
||||||
{
|
{
|
||||||
SIOClientImpl *s = new SIOClientImpl(host, port);
|
SIOClientImpl *s = new SIOClientImpl(host, port);
|
||||||
|
|
||||||
if (s && s->init())
|
if (s && s->init())
|
||||||
{
|
{
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIOClient* SIOClientImpl::getClient(const std::string& endpoint)
|
SIOClient* SIOClientImpl::getClient(const std::string& endpoint)
|
||||||
{
|
{
|
||||||
return _clients.at(endpoint);
|
return _clients.at(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::addClient(const std::string& endpoint, SIOClient* client)
|
void SIOClientImpl::addClient(const std::string& endpoint, SIOClient* client)
|
||||||
{
|
{
|
||||||
_clients.insert(endpoint, client);
|
_clients.insert(endpoint, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::connectToEndpoint(const std::string& endpoint)
|
void SIOClientImpl::connectToEndpoint(const std::string& endpoint)
|
||||||
{
|
{
|
||||||
std::string path = endpoint == "/" ? "" : endpoint;
|
std::string path = endpoint == "/" ? "" : endpoint;
|
||||||
|
|
||||||
std::string s = "1::" + path;
|
std::string s = "1::" + path;
|
||||||
|
|
||||||
_ws->send(s);
|
_ws->send(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::disconnectFromEndpoint(const std::string& endpoint)
|
void SIOClientImpl::disconnectFromEndpoint(const std::string& endpoint)
|
||||||
{
|
{
|
||||||
_clients.erase(endpoint);
|
_clients.erase(endpoint);
|
||||||
|
|
||||||
if (_clients.empty() || endpoint == "/")
|
if (_clients.empty() || endpoint == "/")
|
||||||
{
|
{
|
||||||
log("SIOClientImpl::disconnectFromEndpoint out of endpoints, checking for disconnect");
|
log("SIOClientImpl::disconnectFromEndpoint out of endpoints, checking for disconnect");
|
||||||
|
|
||||||
if(_connected)
|
if(_connected)
|
||||||
this->disconnect();
|
this->disconnect();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string path = endpoint == "/" ? "" : endpoint;
|
std::string path = endpoint == "/" ? "" : endpoint;
|
||||||
|
|
||||||
std::string s = "0::" + path;
|
std::string s = "0::" + path;
|
||||||
|
|
||||||
_ws->send(s);
|
_ws->send(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::heartbeat(float dt)
|
void SIOClientImpl::heartbeat(float dt)
|
||||||
{
|
{
|
||||||
std::string s = "2::";
|
std::string s = "2::";
|
||||||
|
|
||||||
_ws->send(s);
|
_ws->send(s);
|
||||||
|
|
||||||
log("Heartbeat sent");
|
log("Heartbeat sent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SIOClientImpl::send(std::string endpoint, std::string s)
|
void SIOClientImpl::send(std::string endpoint, std::string s)
|
||||||
{
|
{
|
||||||
std::stringstream pre;
|
std::stringstream pre;
|
||||||
|
|
||||||
std::string path = endpoint == "/" ? "" : endpoint;
|
std::string path = endpoint == "/" ? "" : endpoint;
|
||||||
|
|
||||||
pre << "3::" << path << ":" << s;
|
|
||||||
|
|
||||||
std::string msg = pre.str();
|
pre << "3::" << path << ":" << s;
|
||||||
|
|
||||||
log("sending message: %s", msg.c_str());
|
std::string msg = pre.str();
|
||||||
|
|
||||||
_ws->send(msg);
|
log("sending message: %s", msg.c_str());
|
||||||
|
|
||||||
|
_ws->send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::emit(std::string endpoint, std::string eventname, std::string args)
|
void SIOClientImpl::emit(std::string endpoint, std::string eventname, std::string args)
|
||||||
{
|
{
|
||||||
std::stringstream pre;
|
std::stringstream pre;
|
||||||
|
|
||||||
std::string path = endpoint == "/" ? "" : endpoint;
|
std::string path = endpoint == "/" ? "" : endpoint;
|
||||||
|
|
||||||
pre << "5::" << path << ":{\"name\":\"" << eventname << "\",\"args\":" << args << "}";
|
|
||||||
|
|
||||||
std::string msg = pre.str();
|
pre << "5::" << path << ":{\"name\":\"" << eventname << "\",\"args\":" << args << "}";
|
||||||
|
|
||||||
log("emitting event with data: %s", msg.c_str());
|
std::string msg = pre.str();
|
||||||
|
|
||||||
_ws->send(msg);
|
log("emitting event with data: %s", msg.c_str());
|
||||||
|
|
||||||
|
_ws->send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::onOpen(WebSocket* ws)
|
void SIOClientImpl::onOpen(WebSocket* ws)
|
||||||
{
|
{
|
||||||
_connected = true;
|
_connected = true;
|
||||||
|
|
||||||
SocketIO::getInstance()->addSocket(_uri, this);
|
SocketIO::getInstance()->addSocket(_uri, this);
|
||||||
|
|
||||||
for (auto iter = _clients.begin(); iter != _clients.end(); ++iter)
|
for (auto iter = _clients.begin(); iter != _clients.end(); ++iter)
|
||||||
{
|
{
|
||||||
iter->second->onOpen();
|
iter->second->onOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
Director::getInstance()->getScheduler()->schedule(schedule_selector(SIOClientImpl::heartbeat), this, (_heartbeat * .9f), false);
|
Director::getInstance()->getScheduler()->schedule(schedule_selector(SIOClientImpl::heartbeat), this, (_heartbeat * .9f), false);
|
||||||
|
|
||||||
log("SIOClientImpl::onOpen socket connected!");
|
log("SIOClientImpl::onOpen socket connected!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::onMessage(WebSocket* ws, const WebSocket::Data& data)
|
void SIOClientImpl::onMessage(WebSocket* ws, const WebSocket::Data& data)
|
||||||
{
|
{
|
||||||
log("SIOClientImpl::onMessage received: %s", data.bytes);
|
log("SIOClientImpl::onMessage received: %s", data.bytes);
|
||||||
|
|
||||||
int control = atoi(&data.bytes[0]);
|
int control = atoi(&data.bytes[0]);
|
||||||
|
|
||||||
std::string payload, msgid, endpoint, s_data, eventname;
|
std::string payload, msgid, endpoint, s_data, eventname;
|
||||||
payload = data.bytes;
|
payload = data.bytes;
|
||||||
|
|
||||||
size_t pos, pos2;
|
size_t pos, pos2;
|
||||||
|
|
||||||
pos = payload.find(":");
|
pos = payload.find(":");
|
||||||
if(pos != std::string::npos ) {
|
if(pos != std::string::npos ) {
|
||||||
payload.erase(0, pos+1);
|
payload.erase(0, pos+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = payload.find(":");
|
pos = payload.find(":");
|
||||||
if(pos != std::string::npos ) {
|
if(pos != std::string::npos ) {
|
||||||
msgid = atoi(payload.substr(0, pos+1).c_str());
|
msgid = atoi(payload.substr(0, pos+1).c_str());
|
||||||
}
|
}
|
||||||
payload.erase(0, pos+1);
|
payload.erase(0, pos+1);
|
||||||
|
|
||||||
pos = payload.find(":");
|
pos = payload.find(":");
|
||||||
if(pos != std::string::npos)
|
if(pos != std::string::npos)
|
||||||
{
|
{
|
||||||
endpoint = payload.substr(0, pos);
|
endpoint = payload.substr(0, pos);
|
||||||
payload.erase(0, pos+1);
|
payload.erase(0, pos+1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
endpoint = payload;
|
endpoint = payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endpoint == "") endpoint = "/";
|
if (endpoint == "") endpoint = "/";
|
||||||
|
|
||||||
|
|
||||||
s_data = payload;
|
s_data = payload;
|
||||||
SIOClient *c = NULL;
|
SIOClient *c = NULL;
|
||||||
c = getClient(endpoint);
|
c = getClient(endpoint);
|
||||||
if (c == NULL) log("SIOClientImpl::onMessage client lookup returned NULL");
|
if (c == NULL) log("SIOClientImpl::onMessage client lookup returned NULL");
|
||||||
|
|
||||||
switch(control)
|
switch(control)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
log("Received Disconnect Signal for Endpoint: %s\n", endpoint.c_str());
|
log("Received Disconnect Signal for Endpoint: %s\n", endpoint.c_str());
|
||||||
if(c) c->receivedDisconnect();
|
if(c) c->receivedDisconnect();
|
||||||
disconnectFromEndpoint(endpoint);
|
disconnectFromEndpoint(endpoint);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
log("Connected to endpoint: %s \n",endpoint.c_str());
|
log("Connected to endpoint: %s \n",endpoint.c_str());
|
||||||
if(c) c->onConnect();
|
if(c) c->onConnect();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
log("Heartbeat received\n");
|
log("Heartbeat received\n");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
log("Message received: %s \n", s_data.c_str());
|
log("Message received: %s \n", s_data.c_str());
|
||||||
if(c) c->getDelegate()->onMessage(c, s_data);
|
if(c) c->getDelegate()->onMessage(c, s_data);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
log("JSON Message Received: %s \n", s_data.c_str());
|
log("JSON Message Received: %s \n", s_data.c_str());
|
||||||
if(c) c->getDelegate()->onMessage(c, s_data);
|
if(c) c->getDelegate()->onMessage(c, s_data);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
log("Event Received with data: %s \n", s_data.c_str());
|
log("Event Received with data: %s \n", s_data.c_str());
|
||||||
|
|
||||||
if(c)
|
if(c)
|
||||||
{
|
{
|
||||||
eventname = "";
|
eventname = "";
|
||||||
pos = s_data.find(":");
|
pos = s_data.find(":");
|
||||||
pos2 = s_data.find(",");
|
pos2 = s_data.find(",");
|
||||||
if(pos2 > pos)
|
if(pos2 > pos)
|
||||||
{
|
{
|
||||||
s_data = s_data.substr(pos+1, pos2-pos-1);
|
s_data = s_data.substr(pos+1, pos2-pos-1);
|
||||||
std::remove_copy(s_data.begin(), s_data.end(),
|
std::remove_copy(s_data.begin(), s_data.end(),
|
||||||
std::back_inserter(eventname), '"');
|
std::back_inserter(eventname), '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
c->fireEvent(eventname, payload);
|
c->fireEvent(eventname, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
log("Message Ack\n");
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
log("Error\n");
|
|
||||||
if(c) c->getDelegate()->onError(c, s_data);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
log("Noop\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
break;
|
||||||
|
case 6:
|
||||||
|
log("Message Ack\n");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
log("Error\n");
|
||||||
|
if(c) c->getDelegate()->onError(c, s_data);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
log("Noop\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::onClose(WebSocket* ws)
|
void SIOClientImpl::onClose(WebSocket* ws)
|
||||||
|
@ -467,11 +467,11 @@ void SIOClientImpl::onClose(WebSocket* ws)
|
||||||
{
|
{
|
||||||
for (auto iter = _clients.begin(); iter != _clients.end(); ++iter)
|
for (auto iter = _clients.begin(); iter != _clients.end(); ++iter)
|
||||||
{
|
{
|
||||||
iter->second->receivedDisconnect();
|
iter->second->receivedDisconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->release();
|
this->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClientImpl::onError(WebSocket* ws, const WebSocket::ErrorCode& error)
|
void SIOClientImpl::onError(WebSocket* ws, const WebSocket::ErrorCode& error)
|
||||||
|
@ -479,104 +479,106 @@ void SIOClientImpl::onError(WebSocket* ws, const WebSocket::ErrorCode& error)
|
||||||
}
|
}
|
||||||
|
|
||||||
//begin SIOClient methods
|
//begin SIOClient methods
|
||||||
SIOClient::SIOClient(const std::string& host, int port, const std::string& path, SIOClientImpl* impl, SocketIO::SIODelegate& delegate)
|
SIOClient::SIOClient(const std::string& host, int port, const std::string& path, SIOClientImpl* impl, SocketIO::SIODelegate& delegate)
|
||||||
: _port(port)
|
: _port(port)
|
||||||
, _host(host)
|
, _host(host)
|
||||||
, _path(path)
|
, _path(path)
|
||||||
, _connected(false)
|
, _connected(false)
|
||||||
, _socket(impl)
|
, _socket(impl)
|
||||||
, _delegate(&delegate)
|
, _delegate(&delegate)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SIOClient::~SIOClient(void)
|
SIOClient::~SIOClient(void)
|
||||||
{
|
{
|
||||||
if (_connected)
|
if (_connected)
|
||||||
{
|
{
|
||||||
_socket->disconnectFromEndpoint(_path);
|
_socket->disconnectFromEndpoint(_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClient::onOpen()
|
void SIOClient::onOpen()
|
||||||
{
|
{
|
||||||
if (_path != "/")
|
if (_path != "/")
|
||||||
{
|
{
|
||||||
_socket->connectToEndpoint(_path);
|
_socket->connectToEndpoint(_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClient::onConnect()
|
void SIOClient::onConnect()
|
||||||
{
|
{
|
||||||
_connected = true;
|
_connected = true;
|
||||||
_delegate->onConnect(this);
|
_delegate->onConnect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClient::send(std::string s)
|
void SIOClient::send(std::string s)
|
||||||
{
|
{
|
||||||
if (_connected)
|
if (_connected)
|
||||||
{
|
{
|
||||||
_socket->send(_path, s);
|
_socket->send(_path, s);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_delegate->onError(this, "Client not yet connected");
|
_delegate->onError(this, "Client not yet connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClient::emit(std::string eventname, std::string args)
|
void SIOClient::emit(std::string eventname, std::string args)
|
||||||
{
|
{
|
||||||
if(_connected)
|
if(_connected)
|
||||||
{
|
{
|
||||||
_socket->emit(_path, eventname, args);
|
_socket->emit(_path, eventname, args);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_delegate->onError(this, "Client not yet connected");
|
_delegate->onError(this, "Client not yet connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClient::disconnect()
|
void SIOClient::disconnect()
|
||||||
{
|
{
|
||||||
_connected = false;
|
_connected = false;
|
||||||
|
|
||||||
_socket->disconnectFromEndpoint(_path);
|
_socket->disconnectFromEndpoint(_path);
|
||||||
|
|
||||||
_delegate->onClose(this);
|
_delegate->onClose(this);
|
||||||
|
|
||||||
this->release();
|
this->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClient::receivedDisconnect()
|
void SIOClient::receivedDisconnect()
|
||||||
{
|
{
|
||||||
_connected = false;
|
_connected = false;
|
||||||
|
|
||||||
_delegate->onClose(this);
|
_delegate->onClose(this);
|
||||||
|
|
||||||
this->release();
|
this->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClient::on(const std::string& eventName, SIOEvent e)
|
void SIOClient::on(const std::string& eventName, SIOEvent e)
|
||||||
{
|
{
|
||||||
_eventRegistry[eventName] = e;
|
_eventRegistry[eventName] = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIOClient::fireEvent(const std::string& eventName, const std::string& data)
|
void SIOClient::fireEvent(const std::string& eventName, const std::string& data)
|
||||||
{
|
{
|
||||||
log("SIOClient::fireEvent called with event name: %s and data: %s", eventName.c_str(), data.c_str());
|
log("SIOClient::fireEvent called with event name: %s and data: %s", eventName.c_str(), data.c_str());
|
||||||
|
|
||||||
if(_eventRegistry[eventName])
|
_delegate->fireEventToScript(this, eventName, data);
|
||||||
|
|
||||||
|
if(_eventRegistry[eventName])
|
||||||
{
|
{
|
||||||
SIOEvent e = _eventRegistry[eventName];
|
SIOEvent e = _eventRegistry[eventName];
|
||||||
|
|
||||||
e(this, data);
|
e(this, data);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log("SIOClient::fireEvent no event with name %s found", eventName.c_str());
|
log("SIOClient::fireEvent no native event with name %s found", eventName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
//begin SocketIO methods
|
//begin SocketIO methods
|
||||||
|
@ -592,102 +594,109 @@ SocketIO::~SocketIO(void)
|
||||||
|
|
||||||
SocketIO* SocketIO::getInstance()
|
SocketIO* SocketIO::getInstance()
|
||||||
{
|
{
|
||||||
if (nullptr == _inst)
|
if (nullptr == _inst)
|
||||||
_inst = new SocketIO();
|
_inst = new SocketIO();
|
||||||
|
|
||||||
return _inst;
|
return _inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketIO::destroyInstance()
|
void SocketIO::destroyInstance()
|
||||||
{
|
{
|
||||||
CC_SAFE_DELETE(_inst);
|
CC_SAFE_DELETE(_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIOClient* SocketIO::connect(SocketIO::SIODelegate& delegate, const std::string& uri)
|
SIOClient* SocketIO::connect(SocketIO::SIODelegate& delegate, const std::string& uri)
|
||||||
{
|
{
|
||||||
std::string host = uri;
|
|
||||||
int port = 0;
|
return SocketIO::connect(uri, delegate);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SIOClient* SocketIO::connect(const std::string& uri, SocketIO::SIODelegate& delegate)
|
||||||
|
{
|
||||||
|
std::string host = uri;
|
||||||
|
int port = 0;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
|
|
||||||
pos = host.find("//");
|
pos = host.find("//");
|
||||||
if (pos != std::string::npos)
|
if (pos != std::string::npos)
|
||||||
{
|
{
|
||||||
host.erase(0, pos+2);
|
host.erase(0, pos+2);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = host.find(":");
|
pos = host.find(":");
|
||||||
if (pos != std::string::npos)
|
if (pos != std::string::npos)
|
||||||
{
|
{
|
||||||
port = atoi(host.substr(pos+1, host.size()).c_str());
|
port = atoi(host.substr(pos+1, host.size()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = host.find("/", 0);
|
pos = host.find("/", 0);
|
||||||
std::string path = "/";
|
std::string path = "/";
|
||||||
if (pos != std::string::npos)
|
if (pos != std::string::npos)
|
||||||
{
|
{
|
||||||
path += host.substr(pos + 1, host.size());
|
path += host.substr(pos + 1, host.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = host.find(":");
|
pos = host.find(":");
|
||||||
if (pos != std::string::npos)
|
if (pos != std::string::npos)
|
||||||
{
|
{
|
||||||
host.erase(pos, host.size());
|
host.erase(pos, host.size());
|
||||||
}
|
}
|
||||||
else if ((pos = host.find("/")) != std::string::npos)
|
else if ((pos = host.find("/")) != std::string::npos)
|
||||||
{
|
{
|
||||||
host.erase(pos, host.size());
|
host.erase(pos, host.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << host << ":" << port;
|
s << host << ":" << port;
|
||||||
|
|
||||||
SIOClientImpl* socket = nullptr;
|
|
||||||
SIOClient *c = nullptr;
|
|
||||||
|
|
||||||
socket = SocketIO::getInstance()->getSocket(s.str());
|
SIOClientImpl* socket = nullptr;
|
||||||
|
SIOClient *c = nullptr;
|
||||||
|
|
||||||
if(socket == nullptr)
|
socket = SocketIO::getInstance()->getSocket(s.str());
|
||||||
|
|
||||||
|
if(socket == nullptr)
|
||||||
{
|
{
|
||||||
//create a new socket, new client, connect
|
//create a new socket, new client, connect
|
||||||
socket = SIOClientImpl::create(host, port);
|
socket = SIOClientImpl::create(host, port);
|
||||||
|
|
||||||
c = new SIOClient(host, port, path, socket, delegate);
|
c = new SIOClient(host, port, path, socket, delegate);
|
||||||
|
|
||||||
socket->addClient(path, c);
|
|
||||||
|
|
||||||
socket->connect();
|
socket->addClient(path, c);
|
||||||
}
|
|
||||||
|
socket->connect();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//check if already connected to endpoint, handle
|
//check if already connected to endpoint, handle
|
||||||
c = socket->getClient(path);
|
c = socket->getClient(path);
|
||||||
|
|
||||||
if(c == NULL)
|
if(c == NULL)
|
||||||
{
|
{
|
||||||
c = new SIOClient(host, port, path, socket, delegate);
|
c = new SIOClient(host, port, path, socket, delegate);
|
||||||
|
|
||||||
socket->addClient(path, c);
|
|
||||||
|
|
||||||
socket->connectToEndpoint(path);
|
socket->addClient(path, c);
|
||||||
}
|
|
||||||
}
|
socket->connectToEndpoint(path);
|
||||||
|
}
|
||||||
return c;
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIOClientImpl* SocketIO::getSocket(const std::string& uri)
|
SIOClientImpl* SocketIO::getSocket(const std::string& uri)
|
||||||
{
|
{
|
||||||
return _sockets.at(uri);
|
return _sockets.at(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketIO::addSocket(const std::string& uri, SIOClientImpl* socket)
|
void SocketIO::addSocket(const std::string& uri, SIOClientImpl* socket)
|
||||||
{
|
{
|
||||||
_sockets.insert(uri, socket);
|
_sockets.insert(uri, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketIO::removeSocket(const std::string& uri)
|
void SocketIO::removeSocket(const std::string& uri)
|
||||||
{
|
{
|
||||||
_sockets.erase(uri);
|
_sockets.erase(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Copyright (c) 2013 Chris Hannon http://www.channon.us
|
Copyright (c) 2013 Chris Hannon http://www.channon.us
|
||||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
@ -27,32 +27,32 @@ Usage is described below, a full working example can be found in TestCpp under E
|
||||||
|
|
||||||
creating a new connection to a socket.io server running at localhost:3000
|
creating a new connection to a socket.io server running at localhost:3000
|
||||||
|
|
||||||
SIOClient *client = SocketIO::connect(*delegate, "ws://localhost:3000");
|
SIOClient *client = SocketIO::connect(*delegate, "ws://localhost:3000");
|
||||||
|
|
||||||
the connection process will begin and if successful delegate::onOpen will be called
|
the connection process will begin and if successful delegate::onOpen will be called
|
||||||
if the connection process results in an error, delegate::onError will be called with the err msg
|
if the connection process results in an error, delegate::onError will be called with the err msg
|
||||||
|
|
||||||
sending a message to the server
|
sending a message to the server
|
||||||
|
|
||||||
client->send("Hello!");
|
client->send("Hello!");
|
||||||
|
|
||||||
emitting an event to be handled by the server, argument json formatting is up to you
|
emitting an event to be handled by the server, argument json formatting is up to you
|
||||||
|
|
||||||
client->emit("eventname", "[{\"arg\":\"value\"}]");
|
client->emit("eventname", "[{\"arg\":\"value\"}]");
|
||||||
|
|
||||||
registering an event callback, target should be a member function in a subclass of SIODelegate
|
registering an event callback, target should be a member function in a subclass of SIODelegate
|
||||||
CC_CALLBACK_2 is used to wrap the callback with std::bind and store as an SIOEvent
|
CC_CALLBACK_2 is used to wrap the callback with std::bind and store as an SIOEvent
|
||||||
|
|
||||||
client->on("eventname", CC_CALLBACK_2(TargetClass::targetfunc, *targetclass_instance));
|
client->on("eventname", CC_CALLBACK_2(TargetClass::targetfunc, *targetclass_instance));
|
||||||
|
|
||||||
event target function should match this pattern, *this pointer will be made available
|
event target function should match this pattern, *this pointer will be made available
|
||||||
|
|
||||||
void TargetClass::targetfunc(SIOClient *, const std::string&)
|
void TargetClass::targetfunc(SIOClient *, const std::string&)
|
||||||
|
|
||||||
disconnect from the endpoint by calling disconnect(), onClose will be called on the delegate once complete
|
disconnect from the endpoint by calling disconnect(), onClose will be called on the delegate once complete
|
||||||
in the onClose method the pointer should be set to NULL or used to connect to a new endpoint
|
in the onClose method the pointer should be set to NULL or used to connect to a new endpoint
|
||||||
|
|
||||||
client->disconnect();
|
client->disconnect();
|
||||||
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
@ -78,44 +78,47 @@ class SIOClient;
|
||||||
class SocketIO
|
class SocketIO
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static SocketIO* getInstance();
|
static SocketIO* getInstance();
|
||||||
static void destroyInstance();
|
static void destroyInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The delegate class to process socket.io events
|
* @brief The delegate class to process socket.io events
|
||||||
*/
|
*/
|
||||||
class SIODelegate
|
class SIODelegate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~SIODelegate() {}
|
virtual ~SIODelegate() {}
|
||||||
virtual void onConnect(SIOClient* client) = 0;
|
virtual void onConnect(SIOClient* client) = 0;
|
||||||
virtual void onMessage(SIOClient* client, const std::string& data) = 0;
|
virtual void onMessage(SIOClient* client, const std::string& data) = 0;
|
||||||
virtual void onClose(SIOClient* client) = 0;
|
virtual void onClose(SIOClient* client) = 0;
|
||||||
virtual void onError(SIOClient* client, const std::string& data) = 0;
|
virtual void onError(SIOClient* client, const std::string& data) = 0;
|
||||||
|
virtual void fireEventToScript(SIOClient* client, const std::string& eventName, const std::string& data) { CCLOG("SIODelegate event '%s' fired with data: %s", eventName.c_str(), data.c_str()); };
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Static client creation method, similar to socketio.connect(uri) in JS
|
* @brief Static client creation method, similar to socketio.connect(uri) in JS
|
||||||
* @param delegate The delegate which want to receive events from the socket.io client
|
* @param delegate The delegate which want to receive events from the socket.io client
|
||||||
* @param uri The URI of the socket.io server
|
* @param uri The URI of the socket.io server
|
||||||
* @return An initialized SIOClient if connected successfully, otherwise NULL
|
* @return An initialized SIOClient if connected successfully, otherwise NULL
|
||||||
*/
|
*/
|
||||||
static SIOClient* connect(SocketIO::SIODelegate& delegate, const std::string& uri);
|
static SIOClient* connect(const std::string& uri, SocketIO::SIODelegate& delegate);
|
||||||
|
|
||||||
|
CC_DEPRECATED_ATTRIBUTE static SIOClient* connect(SocketIO::SIODelegate& delegate, const std::string& uri);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
SocketIO();
|
SocketIO();
|
||||||
virtual ~SocketIO(void);
|
virtual ~SocketIO(void);
|
||||||
|
|
||||||
static SocketIO *_inst;
|
|
||||||
|
|
||||||
cocos2d::Map<std::string, SIOClientImpl*> _sockets;
|
static SocketIO *_inst;
|
||||||
|
|
||||||
SIOClientImpl* getSocket(const std::string& uri);
|
cocos2d::Map<std::string, SIOClientImpl*> _sockets;
|
||||||
void addSocket(const std::string& uri, SIOClientImpl* socket);
|
|
||||||
void removeSocket(const std::string& uri);
|
|
||||||
|
|
||||||
friend class SIOClientImpl;
|
SIOClientImpl* getSocket(const std::string& uri);
|
||||||
|
void addSocket(const std::string& uri, SIOClientImpl* socket);
|
||||||
|
void removeSocket(const std::string& uri);
|
||||||
|
|
||||||
|
friend class SIOClientImpl;
|
||||||
private:
|
private:
|
||||||
CC_DISALLOW_COPY_AND_ASSIGN(SocketIO)
|
CC_DISALLOW_COPY_AND_ASSIGN(SocketIO)
|
||||||
};
|
};
|
||||||
|
@ -129,59 +132,59 @@ typedef std::unordered_map<std::string, SIOEvent> EventRegistry;
|
||||||
* @brief A single connection to a socket.io endpoint
|
* @brief A single connection to a socket.io endpoint
|
||||||
*/
|
*/
|
||||||
class SIOClient
|
class SIOClient
|
||||||
: public cocos2d::Ref
|
: public cocos2d::Ref
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int _port;
|
int _port;
|
||||||
std::string _host, _path, _tag;
|
std::string _host, _path, _tag;
|
||||||
bool _connected;
|
bool _connected;
|
||||||
SIOClientImpl* _socket;
|
SIOClientImpl* _socket;
|
||||||
|
|
||||||
SocketIO::SIODelegate* _delegate;
|
SocketIO::SIODelegate* _delegate;
|
||||||
|
|
||||||
EventRegistry _eventRegistry;
|
EventRegistry _eventRegistry;
|
||||||
|
|
||||||
void fireEvent(const std::string& eventName, const std::string& data);
|
void fireEvent(const std::string& eventName, const std::string& data);
|
||||||
|
|
||||||
void onOpen();
|
void onOpen();
|
||||||
void onConnect();
|
void onConnect();
|
||||||
void receivedDisconnect();
|
void receivedDisconnect();
|
||||||
|
|
||||||
friend class SIOClientImpl;
|
friend class SIOClientImpl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SIOClient(const std::string& host, int port, const std::string& path, SIOClientImpl* impl, SocketIO::SIODelegate& delegate);
|
SIOClient(const std::string& host, int port, const std::string& path, SIOClientImpl* impl, SocketIO::SIODelegate& delegate);
|
||||||
virtual ~SIOClient(void);
|
virtual ~SIOClient(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the delegate for the client
|
* @brief Returns the delegate for the client
|
||||||
*/
|
*/
|
||||||
SocketIO::SIODelegate* getDelegate() { return _delegate; };
|
SocketIO::SIODelegate* getDelegate() { return _delegate; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disconnect from the endpoint, onClose will be called on the delegate when comlpete
|
* @brief Disconnect from the endpoint, onClose will be called on the delegate when comlpete
|
||||||
*/
|
*/
|
||||||
void disconnect();
|
void disconnect();
|
||||||
/**
|
/**
|
||||||
* @brief Send a message to the socket.io server
|
* @brief Send a message to the socket.io server
|
||||||
*/
|
*/
|
||||||
void send(std::string s);
|
void send(std::string s);
|
||||||
/**
|
/**
|
||||||
* @brief The delegate class to process socket.io events
|
* @brief The delegate class to process socket.io events
|
||||||
*/
|
*/
|
||||||
void emit(std::string eventname, std::string args);
|
void emit(std::string eventname, std::string args);
|
||||||
/**
|
/**
|
||||||
* @brief Used to resgister a socket.io event callback
|
* @brief Used to resgister a socket.io event callback
|
||||||
* Event argument should be passed using CC_CALLBACK2(&Base::function, this)
|
* Event argument should be passed using CC_CALLBACK2(&Base::function, this)
|
||||||
*/
|
*/
|
||||||
void on(const std::string& eventName, SIOEvent e);
|
void on(const std::string& eventName, SIOEvent e);
|
||||||
|
|
||||||
inline void setTag(const char* tag)
|
inline void setTag(const char* tag)
|
||||||
{
|
{
|
||||||
_tag = tag;
|
_tag = tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const char* getTag()
|
inline const char* getTag()
|
||||||
{
|
{
|
||||||
return _tag.c_str();
|
return _tag.c_str();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Copyright (c) 2010-2012 cocos2d-x.org
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||||
|
|
||||||
http://www.cocos2d-x.org
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
@ -59,7 +59,7 @@ public:
|
||||||
* @lua NA
|
* @lua NA
|
||||||
*/
|
*/
|
||||||
virtual ~WebSocket();
|
virtual ~WebSocket();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Data structure for message
|
* @brief Data structure for message
|
||||||
*/
|
*/
|
||||||
|
@ -70,7 +70,7 @@ public:
|
||||||
ssize_t len, issued;
|
ssize_t len, issued;
|
||||||
bool isBinary;
|
bool isBinary;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Errors in websocket
|
* @brief Errors in websocket
|
||||||
*/
|
*/
|
||||||
|
@ -80,7 +80,7 @@ public:
|
||||||
CONNECTION_FAILURE,
|
CONNECTION_FAILURE,
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Websocket state
|
* Websocket state
|
||||||
*/
|
*/
|
||||||
|
@ -104,8 +104,8 @@ public:
|
||||||
virtual void onClose(WebSocket* ws) = 0;
|
virtual void onClose(WebSocket* ws) = 0;
|
||||||
virtual void onError(WebSocket* ws, const ErrorCode& error) = 0;
|
virtual void onError(WebSocket* ws, const ErrorCode& error) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The initialized method for websocket.
|
* @brief The initialized method for websocket.
|
||||||
* It needs to be invoked right after websocket instance is allocated.
|
* It needs to be invoked right after websocket instance is allocated.
|
||||||
|
@ -116,53 +116,53 @@ public:
|
||||||
bool init(const Delegate& delegate,
|
bool init(const Delegate& delegate,
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
const std::vector<std::string>* protocols = nullptr);
|
const std::vector<std::string>* protocols = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends string data to websocket server.
|
* @brief Sends string data to websocket server.
|
||||||
*/
|
*/
|
||||||
void send(const std::string& message);
|
void send(const std::string& message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends binary data to websocket server.
|
* @brief Sends binary data to websocket server.
|
||||||
*/
|
*/
|
||||||
void send(const unsigned char* binaryMsg, unsigned int len);
|
void send(const unsigned char* binaryMsg, unsigned int len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Closes the connection to server.
|
* @brief Closes the connection to server.
|
||||||
*/
|
*/
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets current state of connection.
|
* @brief Gets current state of connection.
|
||||||
*/
|
*/
|
||||||
State getReadyState();
|
State getReadyState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void onSubThreadStarted();
|
virtual void onSubThreadStarted();
|
||||||
virtual int onSubThreadLoop();
|
virtual int onSubThreadLoop();
|
||||||
virtual void onSubThreadEnded();
|
virtual void onSubThreadEnded();
|
||||||
virtual void onUIThreadReceiveMessage(WsMessage* msg);
|
virtual void onUIThreadReceiveMessage(WsMessage* msg);
|
||||||
|
|
||||||
|
|
||||||
friend class WebSocketCallbackWrapper;
|
friend class WebSocketCallbackWrapper;
|
||||||
int onSocketCallback(struct libwebsocket_context *ctx,
|
int onSocketCallback(struct libwebsocket_context *ctx,
|
||||||
struct libwebsocket *wsi,
|
struct libwebsocket *wsi,
|
||||||
int reason,
|
int reason,
|
||||||
void *user, void *in, ssize_t len);
|
void *user, void *in, ssize_t len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
State _readyState;
|
State _readyState;
|
||||||
std::string _host;
|
std::string _host;
|
||||||
unsigned int _port;
|
unsigned int _port;
|
||||||
std::string _path;
|
std::string _path;
|
||||||
|
|
||||||
ssize_t _pendingFrameDataLen;
|
ssize_t _pendingFrameDataLen;
|
||||||
ssize_t _currentDataLen;
|
ssize_t _currentDataLen;
|
||||||
char *_currentData;
|
char *_currentData;
|
||||||
|
|
||||||
friend class WsThreadHelper;
|
friend class WsThreadHelper;
|
||||||
WsThreadHelper* _wsHelper;
|
WsThreadHelper* _wsHelper;
|
||||||
|
|
||||||
struct libwebsocket* _wsInstance;
|
struct libwebsocket* _wsInstance;
|
||||||
struct libwebsocket_context* _wsContext;
|
struct libwebsocket_context* _wsContext;
|
||||||
Delegate* _delegate;
|
Delegate* _delegate;
|
||||||
|
|
Loading…
Reference in New Issue