Fixed part of Cpp to Js callback scopes.

This commit is contained in:
genxium 2023-01-24 20:00:58 +08:00
parent e21e1b840f
commit 6bc3feab58
7 changed files with 65 additions and 28 deletions

View File

@ -547,7 +547,7 @@
"array": [
0,
0,
210.43935996345485,
210.53572189052173,
0,
0,
0,

View File

@ -145,6 +145,16 @@ cc.Class({
JoinIndex: 1,
};
if (cc.sys.isNative) {
window.onUdpMessage = (args) => {
const len = args.length;
const ui8Arr = new Uint8Array(len);
for (let i = 0; i < len; i++) {
ui8Arr[i] = args.charCodeAt(i);
}
cc.log(`#1 Js called back by CPP: onUdpMessage: args=${args}, typeof(args)=${typeof (args)}, argslen=${args.length}, ui8Arr=${ui8Arr}`);
const echoed = window.pb.protos.HolePunchUpsync.decode(ui8Arr);
cc.log(`#2 Js called back by CPP: onUdpMessage: ${JSON.stringify(echoed)}`);
};
DelayNoMore.UdpSession.upsertPeerUdpAddr(self.selfPlayerInfo.JoinIndex, "192.168.31.194", 6789, 123456);
const res1 = DelayNoMore.UdpSession.openUdpSession(8888 + self.selfPlayerInfo.JoinIndex);
const holePunchDate = window.pb.protos.HolePunchUpsync.encode({

View File

@ -66,7 +66,9 @@ window.handleHbRequirements = function(resp) {
}
if (window.handleBattleColliderInfo) {
window.initSecondarySession(null, window.boundRoomId);
if (!cc.sys.isNative) {
window.initSecondarySession(null, window.boundRoomId);
}
window.handleBattleColliderInfo(resp.bciFrame);
}
};

View File

@ -1,10 +1,12 @@
#include "udp_session.hpp"
#include "base/ccMacros.h"
#include "cocos/platform/CCApplication.h"
#include "cocos/base/CCScheduler.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "uv/uv.h"
#include <thread>
uv_udp_t* udpSocket = NULL;
uv_loop_t* loop = NULL; // Only this loop is used for this simple PoC
int const sendBufferLen = 1024;
@ -18,12 +20,34 @@ void _onRead(uv_udp_t* req, ssize_t nread, const uv_buf_t* buf, const struct soc
return;
}
char sender[17] = { 0 };
uv_ip4_name((const struct sockaddr_in*)addr, sender, 16);
CCLOG("Recv from %s", sender);
char senderAddrStr[64] = { 0 };
uv_ip4_name((const struct sockaddr_in*)addr, senderAddrStr, 16);
//uv_udp_recv_stop(req);
int const gameThreadMsgSize = 256;
char* const gameThreadMsg = (char* const)malloc(gameThreadMsgSize);
memset(gameThreadMsg, 0, gameThreadMsgSize);
memcpy(gameThreadMsg, buf->base, nread);
CCLOG("Recv %d bytes from %s, converted to %d bytes for the JS callback", nread, senderAddrStr, strlen(gameThreadMsg));
free(buf->base);
uv_udp_recv_stop(req);
cocos2d::Application::getInstance()->getScheduler()->performFunctionInCocosThread([=]() {
// [WARNING] Use of the "ScriptEngine" is only allowed in "GameThread a.k.a. CocosThread"!
se::Value onUdpMessageCb;
se::ScriptEngine::getInstance()->getGlobalObject()->getProperty("onUdpMessage", &onUdpMessageCb);
// [WARNING] Declaring "AutoHandleScope" is critical here, otherwise "onUdpMessageCb.toObject()" wouldn't be recognized as a function of the ScriptEngine!
se::AutoHandleScope hs;
se::ValueArray args = { se::Value(gameThreadMsg) };
if (onUdpMessageCb.isObject() && onUdpMessageCb.toObject()->isFunction()) {
bool ok = onUdpMessageCb.toObject()->call(args, NULL /* Temporarily assume that the "this" ptr within callback is NULL. */);
if (!ok) {
se::ScriptEngine::getInstance()->clearException();
}
}
free(gameThreadMsg);
});
}
static void _allocBuffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
@ -39,6 +63,7 @@ void startRecvLoop(void* arg) {
}
bool DelayNoMore::UdpSession::openUdpSession(int port) {
uv_mutex_init(&sendLock);
uv_mutex_init(&recvLock);
@ -86,22 +111,6 @@ bool DelayNoMore::UdpSession::upsertPeerUdpAddr(int joinIndex, CHARC* const ip,
return true;
}
void DelayNoMore::UdpSession::onMessage(BYTEC* const bytes) {
se::ScriptEngine* se = se::ScriptEngine::getInstance();
se::Value func;
se->getGlobalObject()->getProperty("onUdpMessage", &func);
se::ValueArray args;
args.push_back(se::Value(bytes));
if (func.isObject() && func.toObject()->isFunction()) {
bool ok = func.toObject()->call(args, NULL /* Temporarily assume that the "this" ptr within callback is NULL. */);
if (!ok) {
se::ScriptEngine::getInstance()->clearException();
}
}
}
void _onSend(uv_udp_send_t* req, int status) {
free(req);
if (status) {
@ -110,12 +119,17 @@ void _onSend(uv_udp_send_t* req, int status) {
}
bool DelayNoMore::UdpSession::punchToServer(BYTEC* const bytes) {
uv_mutex_lock(&sendLock);
/*
[WARNING] The RAM space used for "bytes", either on stack or in heap, is preallocatedand managed by the caller.
Moreover, there's no need to lock on "bytes". Only "udpSocket" is possibly accessed by multiple threads.
*/
uv_udp_send_t* req = (uv_udp_send_t*)malloc(sizeof(uv_udp_send_t));
uv_buf_t sendBuffer = uv_buf_init(bytes, sizeof bytes); // [WARNING] The RAM space used for "bytes", either on stack or in heap, is preallocated and managed by the caller.
uv_buf_t sendBuffer = uv_buf_init(bytes, strlen(bytes));
SOCKADDR_IN destAddr;
uv_ip4_addr("127.0.0.1", 3000, &destAddr);
uv_mutex_lock(&sendLock);
uv_udp_send(req, udpSocket, &sendBuffer, 1, (struct sockaddr const*)&destAddr, _onSend);
uv_mutex_unlock(&sendLock);
return true;

View File

@ -14,7 +14,6 @@ namespace DelayNoMore {
static bool upsertPeerUdpAddr(int joinIndex, CHARC* const ip, int port, uint32_t authKey);
//static bool clearPeerUDPAddrList();
static bool punchToServer(BYTEC* const bytes);
static void onMessage(BYTEC* const bytes);
};
}
#endif

View File

@ -9,6 +9,7 @@ bool openUdpSession(se::State& s) {
if (1 == argc && args[0].isNumber()) {
SE_PRECONDITION2(ok, false, "openUdpSession: Error processing arguments");
int port = args[0].toInt32();
return DelayNoMore::UdpSession::openUdpSession(port);
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d; or wrong arg type!", (int)argc, 1);
@ -27,7 +28,10 @@ bool punchToServer(se::State& s) {
memset(bytes, 0, sizeof bytes);
se::Object* obj = args[0].toObject();
size_t sz = 0;
obj->getTypedArrayData((uint8_t**)&bytes, &sz);
uint8_t* ptr;
obj->getTypedArrayData(&ptr, &sz);
memcpy(bytes, ptr, sz);
CCLOG("Should punch by %d bytes v.s. strlen(bytes)=%u.", sz, strlen(bytes));
return DelayNoMore::UdpSession::punchToServer(bytes);
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d; or wrong arg type!", (int)argc, 1);

View File

@ -26,6 +26,14 @@ func main() {
}
data := strings.TrimSpace(string(message[:rlen]))
fmt.Printf("received: %s from %s\n", data, remote)
fmt.Printf("received: %d bytes, content=%s from %s\n", rlen, data, remote)
// echo
rlen, wrerr := conn.WriteTo(message[0:rlen], remote)
if wrerr != nil {
fmt.Printf("net.WriteTo() error: %s\n", wrerr)
} else {
fmt.Printf("Wrote %d bytes to socket\n", rlen)
}
}
}