背景和头像缺失

This commit is contained in:
2026-03-01 13:51:43 +08:00
parent eaaf7f8c9b
commit 7d2f6399af
5947 changed files with 1441367 additions and 0 deletions

View File

@@ -0,0 +1,376 @@
#include "HttpClientTest.h"
#include "../ExtensionsTest.h"
#include <string>
USING_NS_CC;
USING_NS_CC_EXT;
using namespace cocos2d::network;
HttpClientTests::HttpClientTests()
{
ADD_TEST_CASE(HttpClientTest);
}
HttpClientTest::HttpClientTest()
: _labelStatusCode(nullptr)
{
auto winSize = Director::getInstance()->getWinSize();
const int MARGIN = 40;
const int SPACE = 35;
const int LEFT = winSize.width / 4;
const int RIGHT = winSize.width / 4 * 3;
auto menuRequest = Menu::create();
menuRequest->setPosition(Vec2::ZERO);
addChild(menuRequest);
// Get
auto labelGet = Label::createWithTTF("Test Get", "fonts/arial.ttf", 22);
auto itemGet = MenuItemLabel::create(labelGet, CC_CALLBACK_1(HttpClientTest::onMenuGetTestClicked, this, false));
itemGet->setPosition(LEFT, winSize.height - MARGIN - SPACE);
menuRequest->addChild(itemGet);
// Post
auto labelPost = Label::createWithTTF("Test Post", "fonts/arial.ttf", 22);
auto itemPost = MenuItemLabel::create(labelPost, CC_CALLBACK_1(HttpClientTest::onMenuPostTestClicked, this, false));
itemPost->setPosition(LEFT, winSize.height - MARGIN - 2 * SPACE);
menuRequest->addChild(itemPost);
// Post Binary
auto labelPostBinary = Label::createWithTTF("Test Post Binary", "fonts/arial.ttf", 22);
auto itemPostBinary = MenuItemLabel::create(labelPostBinary, CC_CALLBACK_1(HttpClientTest::onMenuPostBinaryTestClicked, this, false));
itemPostBinary->setPosition(LEFT, winSize.height - MARGIN - 3 * SPACE);
menuRequest->addChild(itemPostBinary);
// Put
auto labelPut = Label::createWithTTF("Test Put", "fonts/arial.ttf", 22);
auto itemPut = MenuItemLabel::create(labelPut, CC_CALLBACK_1(HttpClientTest::onMenuPutTestClicked, this, false));
itemPut->setPosition(LEFT, winSize.height - MARGIN - 4 * SPACE);
menuRequest->addChild(itemPut);
// Delete
auto labelDelete = Label::createWithTTF("Test Delete", "fonts/arial.ttf", 22);
auto itemDelete = MenuItemLabel::create(labelDelete, CC_CALLBACK_1(HttpClientTest::onMenuDeleteTestClicked, this, false));
itemDelete->setPosition(LEFT, winSize.height - MARGIN - 5 * SPACE);
menuRequest->addChild(itemDelete);
// Get for sendImmediate
labelGet = Label::createWithTTF("Test Immediate Get", "fonts/arial.ttf", 22);
itemGet = MenuItemLabel::create(labelGet, CC_CALLBACK_1(HttpClientTest::onMenuGetTestClicked, this, true));
itemGet->setPosition(RIGHT, winSize.height - MARGIN - SPACE);
menuRequest->addChild(itemGet);
// Post for sendImmediate
labelPost = Label::createWithTTF("Test Immediate Post", "fonts/arial.ttf", 22);
itemPost = MenuItemLabel::create(labelPost, CC_CALLBACK_1(HttpClientTest::onMenuPostTestClicked, this, true));
itemPost->setPosition(RIGHT, winSize.height - MARGIN - 2 * SPACE);
menuRequest->addChild(itemPost);
// Post Binary for sendImmediate
labelPostBinary = Label::createWithTTF("Test Immediate Post Binary", "fonts/arial.ttf", 22);
itemPostBinary = MenuItemLabel::create(labelPostBinary, CC_CALLBACK_1(HttpClientTest::onMenuPostBinaryTestClicked, this, true));
itemPostBinary->setPosition(RIGHT, winSize.height - MARGIN - 3 * SPACE);
menuRequest->addChild(itemPostBinary);
// Put for sendImmediate
labelPut = Label::createWithTTF("Test Immediate Put", "fonts/arial.ttf", 22);
itemPut = MenuItemLabel::create(labelPut, CC_CALLBACK_1(HttpClientTest::onMenuPutTestClicked, this, true));
itemPut->setPosition(RIGHT, winSize.height - MARGIN - 4 * SPACE);
menuRequest->addChild(itemPut);
// Delete for sendImmediate
labelDelete = Label::createWithTTF("Test Immediate Delete", "fonts/arial.ttf", 22);
itemDelete = MenuItemLabel::create(labelDelete, CC_CALLBACK_1(HttpClientTest::onMenuDeleteTestClicked, this, true));
itemDelete->setPosition(RIGHT, winSize.height - MARGIN - 5 * SPACE);
menuRequest->addChild(itemDelete);
// Response Code Label
_labelStatusCode = Label::createWithTTF("HTTP Status Code", "fonts/arial.ttf", 18);
_labelStatusCode->setPosition(winSize.width / 2, winSize.height - MARGIN - 6 * SPACE);
addChild(_labelStatusCode);
}
HttpClientTest::~HttpClientTest()
{
HttpClient::destroyInstance();
}
void HttpClientTest::onMenuGetTestClicked(cocos2d::Ref *sender, bool isImmediate)
{
// test 1
{
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl("http://just-make-this-request-failed.com");
request->setRequestType(HttpRequest::Type::GET);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
if (isImmediate)
{
request->setTag("GET immediate test1");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("GET test1");
HttpClient::getInstance()->send(request);
}
request->release();
}
// test 2
{
HttpRequest* request = new (std::nothrow) HttpRequest();
// required fields
request->setUrl("http://httpbin.org/ip");
request->setRequestType(HttpRequest::Type::GET);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
if (isImmediate)
{
request->setTag("GET immediate test2");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("GET test2");
HttpClient::getInstance()->send(request);
}
// don't forget to release it, pair to new
request->release();
}
// test 3
{
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl("https://httpbin.org/get");
request->setRequestType(HttpRequest::Type::GET);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
if (isImmediate)
{
request->setTag("GET immediate test3");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("GET test3");
HttpClient::getInstance()->send(request);
}
request->release();
}
// waiting
_labelStatusCode->setString("waiting...");
}
void HttpClientTest::onMenuPostTestClicked(cocos2d::Ref *sender, bool isImmediate)
{
// test 1
{
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl("http://httpbin.org/post");
request->setRequestType(HttpRequest::Type::POST);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
// write the post data
const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest";
request->setRequestData(postData, strlen(postData));
if (isImmediate)
{
request->setTag("POST immediate test1");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("POST test1");
HttpClient::getInstance()->send(request);
}
request->release();
}
// test 2: set Content-Type
{
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl("http://httpbin.org/post");
request->setRequestType(HttpRequest::Type::POST);
std::vector<std::string> headers;
headers.push_back("Content-Type: application/json; charset=utf-8");
request->setHeaders(headers);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
// write the post data
const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest";
request->setRequestData(postData, strlen(postData));
if (isImmediate)
{
request->setTag("POST immediate test2");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("POST test2");
HttpClient::getInstance()->send(request);
}
request->release();
}
// waiting
_labelStatusCode->setString("waiting...");
}
void HttpClientTest::onMenuPostBinaryTestClicked(cocos2d::Ref *sender, bool isImmediate)
{
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl("http://httpbin.org/post");
request->setRequestType(HttpRequest::Type::POST);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
// write the post data
char postData[22] = "binary=hello\0\0cocos2d"; // including \0, the strings after \0 should not be cut in response
request->setRequestData(postData, 22);
if (isImmediate)
{
request->setTag("POST Binary immediate test");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("POST Binary test");
HttpClient::getInstance()->send(request);
}
request->release();
// waiting
_labelStatusCode->setString("waiting...");
}
void HttpClientTest::onMenuPutTestClicked(Ref *sender, bool isImmediate)
{
// test 1
{
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl("http://httpbin.org/put");
request->setRequestType(HttpRequest::Type::PUT);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
// write the post data
const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest";
request->setRequestData(postData, strlen(postData));
if (isImmediate)
{
request->setTag("PUT Binary immediate test1");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("PUT Binary test1");
HttpClient::getInstance()->send(request);
}
request->release();
}
// test 2: set Content-Type
{
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl("http://httpbin.org/put");
request->setRequestType(HttpRequest::Type::PUT);
std::vector<std::string> headers;
headers.push_back("Content-Type: application/json; charset=utf-8");
request->setHeaders(headers);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
// write the post data
const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest";
request->setRequestData(postData, strlen(postData));
if (isImmediate)
{
request->setTag("PUT Binary immediate test2");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("PUT Binary test2");
HttpClient::getInstance()->send(request);
}
request->release();
}
// waiting
_labelStatusCode->setString("waiting...");
}
void HttpClientTest::onMenuDeleteTestClicked(Ref *sender, bool isImmediate)
{
// test 1
{
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl("http://just-make-this-request-failed.com");
request->setRequestType(HttpRequest::Type::DELETE);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
if (isImmediate)
{
request->setTag("DELETE immediate test1");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("DELETE test1");
HttpClient::getInstance()->send(request);
}
request->release();
}
// test 2
{
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl("http://httpbin.org/delete");
request->setRequestType(HttpRequest::Type::DELETE);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
if (isImmediate)
{
request->setTag("DELETE immediate test2");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("DELETE test2");
HttpClient::getInstance()->send(request);
}
request->release();
}
// waiting
_labelStatusCode->setString("waiting...");
}
void HttpClientTest::onHttpRequestCompleted(HttpClient *sender, HttpResponse *response)
{
if (!response)
{
return;
}
// You can get original request type from: response->request->reqType
if (0 != strlen(response->getHttpRequest()->getTag()))
{
log("%s completed", response->getHttpRequest()->getTag());
}
long statusCode = response->getResponseCode();
char statusString[64] = {};
sprintf(statusString, "HTTP Status Code: %ld, tag = %s", statusCode, response->getHttpRequest()->getTag());
_labelStatusCode->setString(statusString);
log("response code: %ld", statusCode);
if (!response->isSucceed())
{
log("response failed");
log("error buffer: %s", response->getErrorBuffer());
return;
}
// dump data
std::vector<char> *buffer = response->getResponseData();
log("Http Test, dump data: ");
for (unsigned int i = 0; i < buffer->size(); i++)
{
log("%c", (*buffer)[i]);
}
log("\n");
if (response->getHttpRequest()->getReferenceCount() != 2)
{
log("request ref count not 2, is %d", response->getHttpRequest()->getReferenceCount());
}
}

View File

@@ -0,0 +1,35 @@
#ifndef __HTTP_CLIENT_H__
#define __HTTP_CLIENT_H__
#include "cocos2d.h"
#include "extensions/cocos-ext.h"
#include "network/HttpClient.h"
#include "BaseTest.h"
DEFINE_TEST_SUITE(HttpClientTests);
class HttpClientTest : public TestCase
{
public:
CREATE_FUNC(HttpClientTest);
HttpClientTest();
virtual ~HttpClientTest();
//Menu Callbacks
void onMenuGetTestClicked(cocos2d::Ref *sender, bool isImmediate);
void onMenuPostTestClicked(cocos2d::Ref *sender, bool isImmediate);
void onMenuPostBinaryTestClicked(cocos2d::Ref *sender, bool isImmediate);
void onMenuPutTestClicked(cocos2d::Ref *sender, bool isImmediate);
void onMenuDeleteTestClicked(cocos2d::Ref *sender, bool isImmediate);
//Http Response Callback
void onHttpRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response);
virtual std::string title() const override { return "Http Request Test"; }
private:
cocos2d::Label* _labelStatusCode;
};
#endif //__HTTPREQUESTHTTP_H

View File

@@ -0,0 +1,315 @@
/****************************************************************************
Copyright (c) 2015 Chris Hannon http://www.channon.us
Copyright (c) 2013-2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "SocketIOTest.h"
#include "../ExtensionsTest.h"
USING_NS_CC;
USING_NS_CC_EXT;
using namespace cocos2d::network;
SocketIOTests::SocketIOTests()
{
ADD_TEST_CASE(SocketIOTest);
}
SocketIOTest::SocketIOTest()
: _sioClient(nullptr)
, _sioEndpoint(nullptr)
, _sioClientStatus(nullptr)
{//set the clients to nullptr until we are ready to connect
Size winSize = Director::getInstance()->getWinSize();
const int MARGIN = 40;
const int SPACE = 35;
auto menuRequest = Menu::create();
menuRequest->setPosition(Vec2::ZERO);
addChild(menuRequest);
// Test to create basic client in the default namespace
auto labelSIOClient = Label::createWithTTF("Open SocketIO Client", "fonts/arial.ttf", 22);
auto itemSIOClient = MenuItemLabel::create(labelSIOClient, CC_CALLBACK_1(SocketIOTest::onMenuSIOClientClicked, this));
itemSIOClient->setPosition(Vec2(VisibleRect::left().x + labelSIOClient->getContentSize().width / 2 + 5, winSize.height - MARGIN - SPACE));
menuRequest->addChild(itemSIOClient);
// Test to create a client at the endpoint '/testpoint'
auto labelSIOEndpoint = Label::createWithTTF("Open SocketIO Endpoint", "fonts/arial.ttf", 22);
auto itemSIOEndpoint = MenuItemLabel::create(labelSIOEndpoint, CC_CALLBACK_1(SocketIOTest::onMenuSIOEndpointClicked, this));
itemSIOEndpoint->setPosition(Vec2(VisibleRect::right().x - labelSIOEndpoint->getContentSize().width / 2 - 5, winSize.height - MARGIN - SPACE));
menuRequest->addChild(itemSIOEndpoint);
// Test sending message to default namespace
auto labelTestMessage = Label::createWithTTF("Send Test Message", "fonts/arial.ttf", 22);
auto itemTestMessage = MenuItemLabel::create(labelTestMessage, CC_CALLBACK_1(SocketIOTest::onMenuTestMessageClicked, this));
itemTestMessage->setPosition(Vec2(VisibleRect::left().x + labelTestMessage->getContentSize().width / 2 + 5, winSize.height - MARGIN - 2 * SPACE));
menuRequest->addChild(itemTestMessage);
// Test sending message to the endpoint '/testpoint'
auto labelTestMessageEndpoint = Label::createWithTTF("Test Endpoint Message", "fonts/arial.ttf", 22);
auto itemTestMessageEndpoint = MenuItemLabel::create(labelTestMessageEndpoint, CC_CALLBACK_1(SocketIOTest::onMenuTestMessageEndpointClicked, this));
itemTestMessageEndpoint->setPosition(Vec2(VisibleRect::right().x - labelTestMessageEndpoint->getContentSize().width / 2 - 5, winSize.height - MARGIN - 2 * SPACE));
menuRequest->addChild(itemTestMessageEndpoint);
// Test sending event 'echotest' to default namespace
auto labelTestEvent = Label::createWithTTF("Send Test Event", "fonts/arial.ttf", 22);
auto itemTestEvent = MenuItemLabel::create(labelTestEvent, CC_CALLBACK_1(SocketIOTest::onMenuTestEventClicked, this));
itemTestEvent->setPosition(Vec2(VisibleRect::left().x + labelTestEvent->getContentSize().width / 2 + 5, winSize.height - MARGIN - 3 * SPACE));
menuRequest->addChild(itemTestEvent);
// Test sending event 'echotest' to the endpoint '/testpoint'
auto labelTestEventEndpoint = Label::createWithTTF("Test Endpoint Event", "fonts/arial.ttf", 22);
auto itemTestEventEndpoint = MenuItemLabel::create(labelTestEventEndpoint, CC_CALLBACK_1(SocketIOTest::onMenuTestEventEndpointClicked, this));
itemTestEventEndpoint->setPosition(Vec2(VisibleRect::right().x - labelTestEventEndpoint->getContentSize().width / 2 - 5, winSize.height - MARGIN - 3 * SPACE));
menuRequest->addChild(itemTestEventEndpoint);
// Test disconnecting basic client
auto labelTestClientDisconnect = Label::createWithTTF("Disconnect Socket", "fonts/arial.ttf", 22);
auto itemClientDisconnect = MenuItemLabel::create(labelTestClientDisconnect, CC_CALLBACK_1(SocketIOTest::onMenuTestClientDisconnectClicked, this));
itemClientDisconnect->setPosition(Vec2(VisibleRect::left().x + labelTestClientDisconnect->getContentSize().width / 2 + 5, winSize.height - MARGIN - 4 * SPACE));
menuRequest->addChild(itemClientDisconnect);
// Test disconnecting the endpoint '/testpoint'
auto labelTestEndpointDisconnect = Label::createWithTTF("Disconnect Endpoint", "fonts/arial.ttf", 22);
auto itemTestEndpointDisconnect = MenuItemLabel::create(labelTestEndpointDisconnect, CC_CALLBACK_1(SocketIOTest::onMenuTestEndpointDisconnectClicked, this));
itemTestEndpointDisconnect->setPosition(Vec2(VisibleRect::right().x - labelTestEndpointDisconnect->getContentSize().width / 2 - 5, winSize.height - MARGIN - 4 * SPACE));
menuRequest->addChild(itemTestEndpointDisconnect);
// Shared Status Label
_sioClientStatus = Label::createWithTTF("Not connected...", "fonts/arial.ttf", 14, Size(320, 100), TextHAlignment::LEFT);
_sioClientStatus->setAnchorPoint(Vec2(0, 0));
_sioClientStatus->setPosition(Vec2(VisibleRect::left().x, VisibleRect::rightBottom().y));
this->addChild(_sioClientStatus);
}
SocketIOTest::~SocketIOTest(void)
{
}
//test event callback handlers, these will be registered with socket.io
void SocketIOTest::testevent(SIOClient *client, const std::string& data) {
CCLOGINFO("SocketIOTest::testevent called with data: %s", data.c_str());
std::stringstream s;
s << client->getTag() << " received event testevent with data: " << data.c_str();
_sioClientStatus->setString(s.str().c_str());
}
void SocketIOTest::echotest(SIOClient *client, const std::string& data) {
CCLOGINFO("SocketIOTest::echotest called with data: %s", data.c_str());
std::stringstream s;
s << client->getTag() << " received event echotest with data: " << data.c_str();
_sioClientStatus->setString(s.str().c_str());
}
// onMessage is no longer a required override from the delegate class
// 'message' events and handlers are now registered in the same way that other events are
void SocketIOTest::message(network::SIOClient* client, const std::string& data)
{
CCLOGINFO("SocketIOTest::message received: %s", data.c_str());
std::stringstream s;
s << client->getTag() << " received message with content: " << data.c_str();
_sioClientStatus->setString(s.str().c_str());
}
void SocketIOTest::json(network::SIOClient* client, const std::string& data)
{
CCLOGINFO("SocketIOTest::json received: %s", data.c_str());
std::stringstream s;
s << client->getTag() << " received json message with content: " << data.c_str();
_sioClientStatus->setString(s.str().c_str());
}
void SocketIOTest::connect(network::SIOClient* client, const std::string& data)
{
CCLOGINFO("SocketIOTest::connect called");
std::stringstream s;
s << client->getTag() << " connected!";
_sioClientStatus->setString(s.str().c_str());
}
void SocketIOTest::disconnect(network::SIOClient* client, const std::string& data)
{
CCLOGINFO("SocketIOTest::disconnect called");
std::stringstream s;
s << client->getTag() << " disconnected by server!";
_sioClientStatus->setString(s.str().c_str());
this->closedSocketAction(client);
}
void SocketIOTest::closedSocketAction(network::SIOClient* client)
{
//set the local pointer to nullptr or connect to another client
//the client object will be released on its own after this method completes
if (client == _sioClient) {
_sioClient = nullptr;
}
else if (client == _sioEndpoint) {
_sioEndpoint = nullptr;
}
}
void SocketIOTest::onMenuSIOClientClicked(cocos2d::Ref *sender)
{
//create a client by using this static method, url does not need to contain the protocol
_sioClient = SocketIO::connect("ws://localhost:3010", *this);
//you may set a tag for the client for reference in callbacks
_sioClient->setTag("Test Client");
//register event callbacks using the CC_CALLBACK_2() macro and passing the instance of the target class
_sioClient->on("testevent", CC_CALLBACK_2(SocketIOTest::testevent, this));
_sioClient->on("echotest", CC_CALLBACK_2(SocketIOTest::echotest, this));
_sioClient->on("message", CC_CALLBACK_2(SocketIOTest::message, this));
_sioClient->on("json", CC_CALLBACK_2(SocketIOTest::json, this));
_sioClient->on("connect", CC_CALLBACK_2(SocketIOTest::connect, this));
_sioClient->on("disconnect", CC_CALLBACK_2(SocketIOTest::disconnect, this));
}
void SocketIOTest::onMenuSIOEndpointClicked(cocos2d::Ref *sender)
{
//repeat the same connection steps for the namespace "testpoint"
_sioEndpoint = SocketIO::connect("ws://localhost:3010/testpoint", *this);
//a tag to differentiate in shared callbacks
_sioEndpoint->setTag("Test Endpoint");
//demonstrating how callbacks can be shared within a delegate
_sioEndpoint->on("testevent", CC_CALLBACK_2(SocketIOTest::testevent, this));
_sioEndpoint->on("echotest", CC_CALLBACK_2(SocketIOTest::echotest, this));
_sioEndpoint->on("message", CC_CALLBACK_2(SocketIOTest::message, this));
_sioEndpoint->on("json", CC_CALLBACK_2(SocketIOTest::json, this));
_sioEndpoint->on("connect", CC_CALLBACK_2(SocketIOTest::connect, this));
_sioEndpoint->on("disconnect", CC_CALLBACK_2(SocketIOTest::disconnect, this));
}
void SocketIOTest::onMenuTestMessageClicked(cocos2d::Ref *sender)
{
//check that the socket is != nullptr before sending or emitting events
//the client should be nullptr either before initialization and connection or after disconnect
if (_sioClient != nullptr) _sioClient->send("Hello Socket.IO!");
}
void SocketIOTest::onMenuTestMessageEndpointClicked(cocos2d::Ref *sender)
{
if (_sioEndpoint != nullptr) _sioEndpoint->send("Hello Socket.IO!");
}
void SocketIOTest::onMenuTestEventClicked(cocos2d::Ref *sender)
{
//check that the socket is != nullptr before sending or emitting events
//the client should be nullptr either before initialization and connection or after disconnect
if (_sioClient != nullptr) _sioClient->emit("echotest", "{\"name\":\"myname\",\"type\":\"mytype\"}");
}
void SocketIOTest::onMenuTestEventEndpointClicked(cocos2d::Ref *sender)
{
if (_sioEndpoint != nullptr) _sioEndpoint->emit("echotest", "{\"name\":\"myname\",\"type\":\"mytype\"}");
}
void SocketIOTest::onMenuTestClientDisconnectClicked(cocos2d::Ref *sender)
{
// Disconnecting from the default namespace "" or "/" will also disconnect all other endpoints
std::stringstream s;
if (_sioClient != nullptr) {
s << _sioClient->getTag() << " manually closed!";
_sioClient->disconnect();
_sioClient = nullptr;
}
else {
s << "Socket.io Test Client not initialized!";
}
_sioClientStatus->setString(s.str().c_str());
}
void SocketIOTest::onMenuTestEndpointDisconnectClicked(cocos2d::Ref *sender)
{
std::stringstream s;
if (_sioEndpoint != nullptr) {
s << _sioEndpoint->getTag() << " manually closed!";
_sioEndpoint->disconnect();
_sioEndpoint = nullptr;
}
else {
s << "Socket.io Test Endpoint not initialized!";
}
_sioClientStatus->setString(s.str().c_str());
}
// SIODelegate methods to catch network/socket level events outside of the socket.io events
void SocketIOTest::onClose(network::SIOClient* client)
{
CCLOGINFO("SocketIOTest::onClose called");
std::stringstream s;
s << client->getTag() << " closed!";
_sioClientStatus->setString(s.str().c_str());
this->closedSocketAction(client);
}
void SocketIOTest::onError(network::SIOClient* client, const std::string& data)
{
CCLOGERROR("SocketIOTest::onError received: %s", data.c_str());
std::stringstream s;
s << client->getTag() << " received error with content: " << data.c_str();
_sioClientStatus->setString(s.str().c_str());
}

View File

@@ -0,0 +1,108 @@
/****************************************************************************
Copyright (c) 2015 Chris Hannon http://www.channon.us
Copyright (c) 2013-2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __TestCpp__SocketIOTest__
#define __TestCpp__SocketIOTest__
#include "cocos2d.h"
#include "extensions/cocos-ext.h"
#include "network/SocketIO.h"
#include "BaseTest.h"
DEFINE_TEST_SUITE(SocketIOTests);
class SocketIOTest: public TestCase
, public cocos2d::network::SocketIO::SIODelegate
{
public:
CREATE_FUNC(SocketIOTest);
SocketIOTest();
virtual ~SocketIOTest();
/**
* @brief Used for network level socket close (not for disconnect from the socket.io server)
*/
virtual void onClose(cocos2d::network::SIOClient* client)override;
/**
* @brief Used for network level socket error (not for disconnect from the socket.io server)
**/
virtual void onError(cocos2d::network::SIOClient* client, const std::string& data)override;
/**
* @brief Common function to call on both socket.io disconnect and websocket close
**/
void closedSocketAction(cocos2d::network::SIOClient* client);
// test action handlers for main Test Client that connects to defaul namespace "" or "/"
void onMenuSIOClientClicked(cocos2d::Ref *sender);
void onMenuTestMessageClicked(cocos2d::Ref *sender);
void onMenuTestEventClicked(cocos2d::Ref *sender);
void onMenuTestClientDisconnectClicked(cocos2d::Ref *sender);
// test action handlers for Test Endpoint that connects to /testpoint endpoint
void onMenuSIOEndpointClicked(cocos2d::Ref *sender);
void onMenuTestMessageEndpointClicked(cocos2d::Ref *sender);
void onMenuTestEventEndpointClicked(cocos2d::Ref *sender);
void onMenuTestEndpointDisconnectClicked(cocos2d::Ref *sender);
// custom handlers for socket.io related events
/**
* @brief Socket.io event handler for custom event "testevent"
**/
void testevent(cocos2d::network::SIOClient *client, const std::string& data);
/**
* @brief Socket.io event handler for custom event "echoevent"
**/
void echotest(cocos2d::network::SIOClient *client, const std::string& data);
/**
* @brief Socket.io event handler for event "connect"
**/
void connect(cocos2d::network::SIOClient* client, const std::string& data);
/**
* @brief Socket.io event handler for event "disconnect"
**/
void disconnect(cocos2d::network::SIOClient* client, const std::string& data);
/**
* @brief Socket.io event handler for event "message"
**/
void message(cocos2d::network::SIOClient* client, const std::string& data);
/**
* @brief Socket.io event handler for event "json"
* This is only used in v 0.9.x, in 1.x this is handled as a "message" event
**/
void json(cocos2d::network::SIOClient* client, const std::string& data);
virtual std::string title() const override{ return "SocketIO Extension Test"; }
protected:
cocos2d::network::SIOClient *_sioClient, *_sioEndpoint;
cocos2d::Label *_sioClientStatus;
};
#endif /* defined(__TestCpp__SocketIOTest__) */

View File

@@ -0,0 +1,258 @@
#include "WebSocketTest.h"
#include "../ExtensionsTest.h"
USING_NS_CC;
USING_NS_CC_EXT;
WebSocketTests::WebSocketTests()
{
ADD_TEST_CASE(WebSocketTest);
}
WebSocketTest::WebSocketTest()
: _wsiSendText(nullptr)
, _wsiSendBinary(nullptr)
, _wsiError(nullptr)
, _sendTextStatus(nullptr)
, _sendBinaryStatus(nullptr)
, _errorStatus(nullptr)
, _sendTextTimes(0)
, _sendBinaryTimes(0)
{
auto winSize = Director::getInstance()->getWinSize();
const int MARGIN = 40;
const int SPACE = 35;
auto menuRequest = Menu::create();
menuRequest->setPosition(Vec2::ZERO);
addChild(menuRequest);
// Send Text
auto labelSendText = Label::createWithTTF("Send Text", "fonts/arial.ttf", 20);
auto itemSendText = MenuItemLabel::create(labelSendText, CC_CALLBACK_1(WebSocketTest::onMenuSendTextClicked, this));
itemSendText->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - SPACE));
menuRequest->addChild(itemSendText);
labelSendText = Label::createWithTTF("Send Multiple Text", "fonts/arial.ttf", 20);
itemSendText = MenuItemLabel::create(labelSendText, CC_CALLBACK_1(WebSocketTest::onMenuSendMultipleTextClicked, this));
itemSendText->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - 2 * SPACE));
menuRequest->addChild(itemSendText);
// Send Binary
auto labelSendBinary = Label::createWithTTF("Send Binary", "fonts/arial.ttf", 20);
auto itemSendBinary = MenuItemLabel::create(labelSendBinary, CC_CALLBACK_1(WebSocketTest::onMenuSendBinaryClicked, this));
itemSendBinary->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - 3 * SPACE));
menuRequest->addChild(itemSendBinary);
// Send Text Status Label
_sendTextStatus = Label::createWithTTF("Send Text WS is waiting...", "fonts/arial.ttf", 16, Size(160, 100), TextHAlignment::CENTER, TextVAlignment::TOP);
_sendTextStatus->setAnchorPoint(Vec2(0, 0));
_sendTextStatus->setPosition(Vec2(VisibleRect::left().x, VisibleRect::rightBottom().y + 25));
this->addChild(_sendTextStatus);
// Send Binary Status Label
_sendBinaryStatus = Label::createWithTTF("Send Binary WS is waiting...", "fonts/arial.ttf", 16, Size(160, 100), TextHAlignment::CENTER, TextVAlignment::TOP);
_sendBinaryStatus->setAnchorPoint(Vec2(0, 0));
_sendBinaryStatus->setPosition(Vec2(VisibleRect::left().x + 160, VisibleRect::rightBottom().y + 25));
this->addChild(_sendBinaryStatus);
// Error Label
_errorStatus = Label::createWithTTF("Error WS is waiting...", "fonts/arial.ttf", 16, Size(160, 100), TextHAlignment::CENTER, TextVAlignment::TOP);
_errorStatus->setAnchorPoint(Vec2(0, 0));
_errorStatus->setPosition(Vec2(VisibleRect::left().x + 320, VisibleRect::rightBottom().y + 25));
this->addChild(_errorStatus);
auto startTestLabel = Label::createWithTTF("Start Test WebSocket", "fonts/arial.ttf", 16);
auto startTestItem = MenuItemLabel::create(startTestLabel, CC_CALLBACK_1(WebSocketTest::startTestCallback, this));
startTestItem->setPosition(Vec2(VisibleRect::center().x, VisibleRect::bottom().y + 150));
_startTestMenu = Menu::create(startTestItem, nullptr);
_startTestMenu->setPosition(Vec2::ZERO);
this->addChild(_startTestMenu, 1);
}
WebSocketTest::~WebSocketTest()
{
if (_wsiSendText)
_wsiSendText->close();
if (_wsiSendBinary)
_wsiSendBinary->close();
if (_wsiError)
_wsiError->close();
}
void WebSocketTest::startTestCallback(Ref* sender)
{
removeChild(_startTestMenu);
_startTestMenu = nullptr;
_wsiSendText = new network::WebSocket();
_wsiSendBinary = new network::WebSocket();
_wsiError = new network::WebSocket();
if (!_wsiSendText->init(*this, "ws://echo.websocket.org"))
{
CC_SAFE_DELETE(_wsiSendText);
}
if (!_wsiSendBinary->init(*this, "ws://echo.websocket.org"))
{
CC_SAFE_DELETE(_wsiSendBinary);
}
if (!_wsiError->init(*this, "ws://invalid.url.com"))
{
CC_SAFE_DELETE(_wsiError);
}
}
// Delegate methods
void WebSocketTest::onOpen(network::WebSocket* ws)
{
log("Websocket (%p) opened", ws);
if (ws == _wsiSendText)
{
_sendTextStatus->setString("Send Text WS was opened.");
}
else if (ws == _wsiSendBinary)
{
_sendBinaryStatus->setString("Send Binary WS was opened.");
}
else if (ws == _wsiError)
{
CCASSERT(0, "error test will never go here.");
}
}
void WebSocketTest::onMessage(network::WebSocket* ws, const network::WebSocket::Data& data)
{
if (!data.isBinary)
{
_sendTextTimes++;
char times[100] = {0};
sprintf(times, "%d", _sendTextTimes);
std::string textStr = std::string("response text msg: ")+data.bytes+", "+times;
log("%s", textStr.c_str());
_sendTextStatus->setString(textStr.c_str());
}
else
{
_sendBinaryTimes++;
char times[100] = {0};
sprintf(times, "%d", _sendBinaryTimes);
std::string binaryStr = "response bin msg: ";
for (int i = 0; i < data.len; ++i) {
if (data.bytes[i] != '\0')
{
binaryStr += data.bytes[i];
}
else
{
binaryStr += "\'\\0\'";
}
}
binaryStr += std::string(", ")+times;
log("%s", binaryStr.c_str());
_sendBinaryStatus->setString(binaryStr.c_str());
}
}
void WebSocketTest::onClose(network::WebSocket* ws)
{
log("websocket instance (%p) closed.", ws);
if (ws == _wsiSendText)
{
_wsiSendText = nullptr;
}
else if (ws == _wsiSendBinary)
{
_wsiSendBinary = nullptr;
}
else if (ws == _wsiError)
{
_wsiError = nullptr;
}
// Delete websocket instance.
CC_SAFE_DELETE(ws);
}
void WebSocketTest::onError(network::WebSocket* ws, const network::WebSocket::ErrorCode& error)
{
log("Error was fired, error code: %d", error);
if (ws == _wsiError)
{
char buf[100] = {0};
sprintf(buf, "an error was fired, code: %d", error);
_errorStatus->setString(buf);
}
}
// Menu Callbacks
void WebSocketTest::onMenuSendTextClicked(cocos2d::Ref *sender)
{
if (! _wsiSendText)
{
return;
}
if (_wsiSendText->getReadyState() == network::WebSocket::State::OPEN)
{
_sendTextStatus->setString("Send Text WS is waiting...");
_wsiSendText->send("Hello WebSocket, I'm a text message.");
}
else
{
std::string warningStr = "send text websocket instance wasn't ready...";
log("%s", warningStr.c_str());
_sendTextStatus->setString(warningStr.c_str());
}
}
void WebSocketTest::onMenuSendMultipleTextClicked(cocos2d::Ref *sender)
{
if (! _wsiSendText)
{
return;
}
if (_wsiSendText->getReadyState() == network::WebSocket::State::OPEN)
{
_sendTextStatus->setString("Send Multiple Text WS is waiting...");
for (int index = 0; index < 15; ++index) {
_wsiSendText->send(StringUtils::format("Hello WebSocket, text message index:%d", index));
}
}
else
{
std::string warningStr = "send text websocket instance wasn't ready...";
log("%s", warningStr.c_str());
_sendTextStatus->setString(warningStr.c_str());
}
}
void WebSocketTest::onMenuSendBinaryClicked(cocos2d::Ref *sender)
{
if (! _wsiSendBinary) {
return;
}
if (_wsiSendBinary->getReadyState() == network::WebSocket::State::OPEN)
{
_sendBinaryStatus->setString("Send Binary WS is waiting...");
char buf[] = "Hello WebSocket,\0 I'm\0 a\0 binary\0 message\0.";
_wsiSendBinary->send((unsigned char*)buf, sizeof(buf));
}
else
{
std::string warningStr = "send binary websocket instance wasn't ready...";
log("%s", warningStr.c_str());
_sendBinaryStatus->setString(warningStr.c_str());
}
}

View File

@@ -0,0 +1,55 @@
//
// WebSocketTest.h
// TestCpp
//
// Created by James Chen on 5/31/13.
//
//
#ifndef __TestCpp__WebSocketTest__
#define __TestCpp__WebSocketTest__
#include "cocos2d.h"
#include "extensions/cocos-ext.h"
#include "network/WebSocket.h"
#include "BaseTest.h"
DEFINE_TEST_SUITE(WebSocketTests);
class WebSocketTest : public TestCase
, public cocos2d::network::WebSocket::Delegate
{
public:
CREATE_FUNC(WebSocketTest);
WebSocketTest();
virtual ~WebSocketTest();
virtual void onOpen(cocos2d::network::WebSocket* ws)override;
virtual void onMessage(cocos2d::network::WebSocket* ws, const cocos2d::network::WebSocket::Data& data)override;
virtual void onClose(cocos2d::network::WebSocket* ws)override;
virtual void onError(cocos2d::network::WebSocket* ws, const cocos2d::network::WebSocket::ErrorCode& error)override;
// Menu Callbacks
void onMenuSendTextClicked(cocos2d::Ref *sender);
void onMenuSendMultipleTextClicked(cocos2d::Ref *sender);
void onMenuSendBinaryClicked(cocos2d::Ref *sender);
virtual std::string title() const override { return "WebSocket Test"; }
void startTestCallback(cocos2d::Ref* sender);
private:
cocos2d::network::WebSocket* _wsiSendText;
cocos2d::network::WebSocket* _wsiSendBinary;
cocos2d::network::WebSocket* _wsiError;
cocos2d::Label* _sendTextStatus;
cocos2d::Label* _sendBinaryStatus;
cocos2d::Label* _errorStatus;
cocos2d::Menu* _startTestMenu;
int _sendTextTimes;
int _sendBinaryTimes;
};
#endif /* defined(__TestCpp__WebSocketTest__) */