Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cocos/2d/CCSprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ CC_CONSTRUCTOR_ACCESS :
PolygonInfo _polyInfo;

// opacity and RGB protocol
bool _opacityModifyRGB;
bool _opacityModifyRGB = false;

// image is flipped
bool _flippedX; /// Whether the sprite is flipped horizontally or not
Expand Down
128 changes: 71 additions & 57 deletions cocos/network/SocketIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include "network/HttpClient.h"
#include "network/Uri.h"
#include "network/WebSocket.h"

#include <memory>
#include <algorithm>
#include <iterator>
#include <sstream>
Expand Down Expand Up @@ -80,8 +82,8 @@ class SocketIOPacket
std::vector<std::string> getData()const{ return _args; };
virtual std::string stringify()const;

static SocketIOPacket * createPacketWithType(const std::string& type, SocketIOVersion version);
static SocketIOPacket * createPacketWithTypeIndex(int type, SocketIOVersion version);
static std::shared_ptr<SocketIOPacket> createPacketWithType(const std::string& type, SocketIOVersion version);
static std::shared_ptr<SocketIOPacket> createPacketWithTypeIndex(int type, SocketIOVersion version);
protected:
std::string _pId;//id message
std::string _ack;//
Expand Down Expand Up @@ -306,46 +308,47 @@ SocketIOPacketV10x::~SocketIOPacketV10x()
_endpoint = "";
}

SocketIOPacket * SocketIOPacket::createPacketWithType(const std::string& type, SocketIOPacket::SocketIOVersion version)
std::shared_ptr<SocketIOPacket> SocketIOPacket::createPacketWithType(const std::string& type, SocketIOPacket::SocketIOVersion version)
{
SocketIOPacket *ret;
switch (version)
if(version == SocketIOPacket::SocketIOVersion::V09x)
{
case SocketIOPacket::SocketIOVersion::V09x:
ret = new (std::nothrow) SocketIOPacket;
break;
case SocketIOPacket::SocketIOVersion::V10x:
ret = new (std::nothrow) SocketIOPacketV10x;
break;
auto ret = std::make_shared<SocketIOPacket>();
ret->initWithType(type);
return ret;
}
else if(version == SocketIOPacket::SocketIOVersion::V10x)
{
auto ret = std::make_shared<SocketIOPacketV10x>();
ret->initWithType(type);
return ret;
}
ret->initWithType(type);
return ret;
return nullptr;
}


SocketIOPacket * SocketIOPacket::createPacketWithTypeIndex(int type, SocketIOPacket::SocketIOVersion version)
std::shared_ptr<SocketIOPacket> SocketIOPacket::createPacketWithTypeIndex(int type, SocketIOPacket::SocketIOVersion version)
{
SocketIOPacket *ret;
switch (version)
if(version == SocketIOPacket::SocketIOVersion::V09x)
{
case SocketIOPacket::SocketIOVersion::V09x:
ret = new (std::nothrow) SocketIOPacket;
break;
case SocketIOPacket::SocketIOVersion::V10x:
return new (std::nothrow) SocketIOPacketV10x;
break;
auto ret = std::make_shared<SocketIOPacket>();
ret->initWithTypeIndex(type);
return ret;
}
ret->initWithTypeIndex(type);
return ret;
else if(version == SocketIOPacket::SocketIOVersion::V10x)
{
auto ret = std::make_shared<SocketIOPacketV10x>();
ret->initWithTypeIndex(type);
return ret;
}
return nullptr;
}

/**
* @brief The implementation of the socket.io connection
* Clients/endpoints may share the same impl to accomplish multiplexing on the same websocket
*/
class SIOClientImpl :
public cocos2d::Ref,
public WebSocket::Delegate
public WebSocket::Delegate,
public std::enable_shared_from_this<SIOClientImpl>
{
private:
int _heartbeat, _timeout;
Expand All @@ -363,7 +366,7 @@ class SIOClientImpl :
SIOClientImpl(const Uri& uri, const std::string& caFilePath);
virtual ~SIOClientImpl();

static SIOClientImpl* create(const Uri& uri, const std::string& caFilePath);
static std::shared_ptr<SIOClientImpl> create(const Uri& uri, const std::string& caFilePath);

virtual void onOpen(WebSocket* ws);
virtual void onMessage(WebSocket* ws, const WebSocket::Data& data);
Expand All @@ -386,7 +389,7 @@ class SIOClientImpl :

void send(const std::string& endpoint, const std::string& s);
void send(const std::string& endpoint, const std::vector<std::string>& s);
void send(SocketIOPacket *packet);
void send(std::shared_ptr<SocketIOPacket>& packet);
void emit(const std::string& endpoint, const std::string& eventname, const std::string& args);
void emit(const std::string& endpoint, const std::string& eventname, const std::vector<std::string>& args);

Expand Down Expand Up @@ -430,7 +433,14 @@ void SIOClientImpl::handshake()
request->setUrl(pre.str());
request->setRequestType(HttpRequest::Type::GET);

request->setResponseCallback(CC_CALLBACK_2(SIOClientImpl::handshakeResponse, this));
std::weak_ptr<SIOClientImpl> self = shared_from_this();
auto callback = [self](HttpClient* client, HttpResponse *resp) {
auto conn = self.lock();
if (conn) {
conn->handshakeResponse(client, resp);
}
};
request->setResponseCallback(callback);
request->setTag("handshake");

CCLOGINFO("SIOClientImpl::handshake() waiting");
Expand Down Expand Up @@ -627,13 +637,13 @@ void SIOClientImpl::disconnect()
_ws->close();
}

SIOClientImpl* SIOClientImpl::create(const Uri& uri, const std::string& caFilePath)
std::shared_ptr<SIOClientImpl> SIOClientImpl::create(const Uri& uri, const std::string& caFilePath)
{
SIOClientImpl *s = new (std::nothrow) SIOClientImpl(uri, caFilePath);

if (s && s->init())
{
return s;
return std::shared_ptr<SIOClientImpl>(s);
}

return nullptr;
Expand All @@ -651,7 +661,7 @@ void SIOClientImpl::addClient(const std::string& endpoint, SIOClient* client)

void SIOClientImpl::connectToEndpoint(const std::string& endpoint)
{
SocketIOPacket *packet = SocketIOPacket::createPacketWithType("connect", _version);
auto packet = SocketIOPacket::createPacketWithType("connect", _version);
packet->setEndpoint(endpoint);
this->send(packet);
}
Expand Down Expand Up @@ -679,7 +689,7 @@ void SIOClientImpl::disconnectFromEndpoint(const std::string& endpoint)

void SIOClientImpl::heartbeat(float /*dt*/)
{
SocketIOPacket *packet = SocketIOPacket::createPacketWithType("heartbeat", _version);
auto packet = SocketIOPacket::createPacketWithType("heartbeat", _version);

this->send(packet);

Expand All @@ -692,7 +702,7 @@ void SIOClientImpl::send(const std::string& endpoint, const std::vector<std::str
switch (_version) {
case SocketIOPacket::SocketIOVersion::V09x:
{
SocketIOPacket *packet = SocketIOPacket::createPacketWithType("message", _version);
auto packet = SocketIOPacket::createPacketWithType("message", _version);
packet->setEndpoint(endpoint);
for(auto &i : s)
{
Expand All @@ -715,7 +725,7 @@ void SIOClientImpl::send(const std::string& endpoint, const std::string& s)
send(endpoint, t);
}

void SIOClientImpl::send(SocketIOPacket *packet)
void SIOClientImpl::send(std::shared_ptr<SocketIOPacket>& packet)
{
std::string req = packet->toString();
if (_connected)
Expand All @@ -730,7 +740,7 @@ void SIOClientImpl::send(SocketIOPacket *packet)
void SIOClientImpl::emit(const std::string& endpoint, const std::string& eventname, const std::string& args)
{
CCLOGINFO("Emitting event \"%s\"", eventname.c_str());
SocketIOPacket *packet = SocketIOPacket::createPacketWithType("event", _version);
auto packet = SocketIOPacket::createPacketWithType("event", _version);
packet->setEndpoint(endpoint == "/" ? "" : endpoint);
packet->setEvent(eventname);
packet->addData(args);
Expand All @@ -740,7 +750,7 @@ void SIOClientImpl::emit(const std::string& endpoint, const std::string& eventna
void SIOClientImpl::emit(const std::string& endpoint, const std::string& eventname, const std::vector<std::string>& args)
{
CCLOGINFO("Emitting event \"%s\"", eventname.c_str());
SocketIOPacket *packet = SocketIOPacket::createPacketWithType("event", _version);
auto packet = SocketIOPacket::createPacketWithType("event", _version);
packet->setEndpoint(endpoint == "/" ? "" : endpoint);
packet->setEvent(eventname);
for (auto &arg : args) {
Expand All @@ -753,22 +763,30 @@ void SIOClientImpl::onOpen(WebSocket* /*ws*/)
{
_connected = true;

SocketIO::getInstance()->addSocket(_uri.getAuthority(), this);
auto self = shared_from_this();

SocketIO::getInstance()->addSocket(_uri.getAuthority(), self);

if (_version == SocketIOPacket::SocketIOVersion::V10x)
{
std::string s = "5";//That's a ping https://github.com/Automattic/engine.io-parser/blob/1b8e077b2218f4947a69f5ad18be2a512ed54e93/lib/index.js#L21
_ws->send(s);
}

Director::getInstance()->getScheduler()->schedule(CC_SCHEDULE_SELECTOR(SIOClientImpl::heartbeat), this, (_heartbeat * .9f), false);
std::weak_ptr<SIOClientImpl> selfWeak = shared_from_this();
auto f = [selfWeak](float dt) {
auto conn = selfWeak.lock();
if(conn)
conn->heartbeat(dt);
};

Director::getInstance()->getScheduler()->schedule(f, this, (_heartbeat * .9f), false, "heart_beat");

for (auto& client : _clients)
{
client.second->onOpen();
}

CCLOGINFO("SIOClientImpl::onOpen socket connected!");
}

void SIOClientImpl::onMessage(WebSocket* /*ws*/, const WebSocket::Data& data)
Expand Down Expand Up @@ -1012,11 +1030,9 @@ void SIOClientImpl::onClose(WebSocket* /*ws*/)
_connected = false;
if (Director::getInstance())
Director::getInstance()->getScheduler()->unscheduleAllForTarget(this);

SocketIO::getInstance()->removeSocket(_uri.getAuthority());
}

this->release();
}

void SIOClientImpl::onError(WebSocket* /*ws*/, const WebSocket::ErrorCode& error)
Expand All @@ -1025,13 +1041,12 @@ void SIOClientImpl::onError(WebSocket* /*ws*/, const WebSocket::ErrorCode& error
}

//begin SIOClient methods
SIOClient::SIOClient(const std::string& path, SIOClientImpl* impl, SocketIO::SIODelegate& delegate)
SIOClient::SIOClient(const std::string& path, std::shared_ptr<SIOClientImpl>& impl, SocketIO::SIODelegate& delegate)
: _path(path)
, _connected(false)
, _socket(impl)
, _delegate(&delegate)
{
CC_SAFE_RETAIN(_socket);
}

SIOClient::~SIOClient()
Expand All @@ -1040,7 +1055,6 @@ SIOClient::~SIOClient()
{
_socket->disconnectFromEndpoint(_path);
}
CC_SAFE_RELEASE(_socket);
}

void SIOClient::onOpen()
Expand Down Expand Up @@ -1108,15 +1122,13 @@ void SIOClient::disconnect()
{
setConnected(false);
_socket->disconnectFromEndpoint(_path);

this->release();
}

void SIOClient::socketClosed()
{
setConnected(false);
_delegate->onClose(this);

this->release();
}

Expand All @@ -1125,7 +1137,7 @@ bool SIOClient::isConnected() const
return _connected && _socket && _socket->_connected ;
}

void SIOClient::setConnected(bool connected)
void SIOClient::setConnected(bool connected)
{
_connected = connected;
}
Expand Down Expand Up @@ -1196,8 +1208,8 @@ SIOClient* SocketIO::connect(const std::string& uri, SocketIO::SIODelegate& dele
{
Uri uriObj = Uri::parse(uri);

SIOClientImpl *socket = SocketIO::getInstance()->getSocket(uriObj.getAuthority());
SIOClient *c = nullptr;
std::shared_ptr<SIOClientImpl> socket = SocketIO::getInstance()->getSocket(uriObj.getAuthority());
SIOClient * c = nullptr;

std::string path = uriObj.getPath();
if (path.empty())
Expand Down Expand Up @@ -1233,7 +1245,7 @@ SIOClient* SocketIO::connect(const std::string& uri, SocketIO::SIODelegate& dele
c->disconnect();

CCLOG("SocketIO: recreate a new socket, new client, connect");
SIOClientImpl* newSocket = SIOClientImpl::create(uriObj, caFilePath);
std::shared_ptr<SIOClientImpl> newSocket = SIOClientImpl::create(uriObj, caFilePath);
SIOClient *newC = new (std::nothrow) SIOClient(path, newSocket, delegate);

newSocket->addClient(path, newC);
Expand All @@ -1246,14 +1258,16 @@ SIOClient* SocketIO::connect(const std::string& uri, SocketIO::SIODelegate& dele
return c;
}

SIOClientImpl* SocketIO::getSocket(const std::string& uri)
std::shared_ptr<SIOClientImpl> SocketIO::getSocket(const std::string& uri)
{
return _sockets.at(uri);
auto p = _sockets.find(uri);
if(p == _sockets.end()) return nullptr;
return p->second.lock();
}

void SocketIO::addSocket(const std::string& uri, SIOClientImpl* socket)
void SocketIO::addSocket(const std::string& uri, std::shared_ptr<SIOClientImpl>& socket)
{
_sockets.insert(uri, socket);
_sockets.emplace(uri, socket);
}

void SocketIO::removeSocket(const std::string& uri)
Expand Down
15 changes: 8 additions & 7 deletions cocos/network/SocketIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,11 @@ class CC_DLL SocketIO

static SocketIO *_inst;

cocos2d::Map<std::string, SIOClientImpl*> _sockets;
std::unordered_map<std::string, std::weak_ptr<SIOClientImpl
>> _sockets;

SIOClientImpl* getSocket(const std::string& uri);
void addSocket(const std::string& uri, SIOClientImpl* socket);
std::shared_ptr<SIOClientImpl> getSocket(const std::string& uri);
void addSocket(const std::string& uri, std::shared_ptr<SIOClientImpl>& socket);
void removeSocket(const std::string& uri);

friend class SIOClientImpl;
Expand All @@ -210,9 +211,9 @@ class CC_DLL SIOClient

std::string _path, _tag;
bool _connected;
SIOClientImpl* _socket;

SocketIO::SIODelegate* _delegate;
std::shared_ptr<SIOClientImpl> _socket;
SocketIO::SIODelegate* _delegate = nullptr;

EventRegistry _eventRegistry;

Expand All @@ -236,7 +237,7 @@ class CC_DLL SIOClient
* @param impl the SIOClientImpl object.
* @param delegate the SIODelegate object.
*/
SIOClient(const std::string& path, SIOClientImpl* impl, SocketIO::SIODelegate& delegate);
SIOClient(const std::string& path, std::shared_ptr<SIOClientImpl>& impl, SocketIO::SIODelegate& delegate);
/**
* Destructor of SIOClient class.
*/
Expand Down
Loading