diff --git a/frontend/assets/scripts/WsSessionMgr.js b/frontend/assets/scripts/WsSessionMgr.js index da7a2e2..dd9eb2b 100644 --- a/frontend/assets/scripts/WsSessionMgr.js +++ b/frontend/assets/scripts/WsSessionMgr.js @@ -229,7 +229,11 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) { const peerJoinIndex = resp.peerJoinIndex; const peerAddrList = resp.rdf.peerUdpAddrList; console.log(`Got DOWNSYNC_MSG_ACT_PEER_UDP_ADDR peerAddrList=${JSON.stringify(peerAddrList)}; boundRoomCapacity=${window.boundRoomCapacity}`); - DelayNoMore.UdpSession.upsertPeerUdpAddr(peerAddrList, window.boundRoomCapacity, window.mapIns.selfPlayerInfo.JoinIndex); // In C++ impl it actually broadcasts the peer-punching message to all known peers within "window.boundRoomCapacity" + for (let j = 0; j < 3; ++j) { + setTimeout(()=> { + DelayNoMore.UdpSession.upsertPeerUdpAddr(peerAddrList, window.boundRoomCapacity, window.mapIns.selfPlayerInfo.JoinIndex); // In C++ impl it actually broadcasts the peer-punching message to all known peers within "window.boundRoomCapacity" + }, j*500); + } } break; default: diff --git a/frontend/build-templates/jsb-link/cocos-project-template.json b/frontend/build-templates/jsb-link/cocos-project-template.json index 8744f8a..1856b9c 100644 --- a/frontend/build-templates/jsb-link/cocos-project-template.json +++ b/frontend/build-templates/jsb-link/cocos-project-template.json @@ -20,6 +20,9 @@ }, { "from": "frameworks/runtime-src/Classes/send_ring_buff.hpp", "to": "frameworks/runtime-src/Classes/send_ring_buff.hpp" + }, { + "from": "frameworks/runtime-src/Classes/send_ring_buff.cpp", + "to": "frameworks/runtime-src/Classes/send_ring_buff.cpp" }, { "from": "frameworks/runtime-src/Classes/udp_session.hpp", "to": "frameworks/runtime-src/Classes/udp_session.hpp" diff --git a/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/send_ring_buff.cpp b/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/send_ring_buff.cpp new file mode 100644 index 0000000..7dd2f9c --- /dev/null +++ b/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/send_ring_buff.cpp @@ -0,0 +1,31 @@ +#include +#include "send_ring_buff.hpp" + +void SendRingBuff::put(BYTEC* const newBytes, size_t newBytesLen, PeerAddr* pNewPeerAddr) { + while (0 < cnt && cnt >= n) { + // Make room for the new element + this->pop(); + } + eles[ed].bytesLen = newBytesLen; + memset(eles[ed].bytes, 0, sizeof eles[ed].bytes); + memcpy(eles[ed].bytes, newBytes, newBytesLen); + eles[ed].peerAddr = *(pNewPeerAddr); + ed++; + cnt++; + if (ed >= n) { + ed -= n; // Deliberately not using "%" operator for performance concern + } +} + +SendWork* SendRingBuff::pop() { + if (0 == cnt) { + return NULL; + } + SendWork* ret = &(eles[st]); + cnt--; + st++; + if (st >= n) { + st -= n; + } + return ret; +} diff --git a/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/send_ring_buff.hpp b/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/send_ring_buff.hpp index 81c3854..a7a3758 100644 --- a/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/send_ring_buff.hpp +++ b/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/send_ring_buff.hpp @@ -26,44 +26,19 @@ public: }; // [WARNING] This class is specific to "SendWork", designed and implemented only to use in multithreading env and save heap alloc/dealloc timecomplexity, it's by no means comparable to the Golang or JavaScript versions! -class SendRingBuffer { +class SendRingBuff { public: int ed, st, n, cnt; SendWork eles[maxBuffedMsgs]; // preallocated on stack to save heap alloc/dealloc time - SendRingBuffer(int newN) { + SendRingBuff(int newN) { this->n = newN; this->st = this->ed = this->cnt = 0; } - void put(BYTEC* const newBytes, size_t newBytesLen, PeerAddr* pNewPeerAddr) { - while (0 < cnt && cnt >= n) { - // Make room for the new element - this->pop(); - } - eles[ed].bytesLen = newBytesLen; - memset(eles[ed].bytes, 0, sizeof eles[ed].bytes); - memcpy(eles[ed].bytes, newBytes, newBytesLen); - eles[ed].peerAddr = *(pNewPeerAddr); - ed++; - cnt++; - if (ed >= n) { - ed -= n; // Deliberately not using "%" operator for performance concern - } - } + void put(BYTEC* const newBytes, size_t newBytesLen, PeerAddr* pNewPeerAddr); // Sending is always sequential in UvSendThread, no need to return a copy of "SendWork" instance - SendWork* pop() { - if (0 == cnt) { - return NULL; - } - SendWork* ret = &(eles[st]); - cnt--; - st++; - if (st >= n) { - st -= n; - } - return ret; - } + SendWork* pop(); }; -#endif \ No newline at end of file +#endif diff --git a/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/udp_session.cpp b/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/udp_session.cpp index c2c60b1..e0e89b2 100644 --- a/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/udp_session.cpp +++ b/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/udp_session.cpp @@ -6,7 +6,7 @@ int const punchServerCnt = 3; int const punchPeerCnt = 3; -int const broadcastUpsyncCnt = 3; +int const broadcastUpsyncCnt = 1; uv_udp_t *udpRecvSocket = NULL, *udpSendSocket = NULL; uv_thread_t recvTid, sendTid; @@ -14,7 +14,7 @@ uv_async_t uvRecvLoopStopSig, uvSendLoopStopSig, uvSendLoopTriggerSig; uv_loop_t *recvLoop = NULL, *sendLoop = NULL; uv_mutex_t sendRingBuffLock; // used along with "uvSendLoopTriggerSig" as a "uv_cond_t" -SendRingBuffer* sendRingBuff = NULL; +SendRingBuff* sendRingBuff = NULL; char SRV_IP[256]; int SRV_PORT = 0; @@ -41,14 +41,14 @@ void _onRead(uv_udp_t* req, ssize_t nread, uv_buf_t const* buf, struct sockaddr struct sockaddr_in const* sockAddr = (struct sockaddr_in const*)addr; uv_inet_ntop(sockAddr->sin_family, &(sockAddr->sin_addr), ip, INET_ADDRSTRLEN); port = ntohs(sockAddr->sin_port); - CCLOG("UDP received %d bytes from %s:%d", nread, ip, port); + CCLOG("UDP received %u bytes from %s:%d", nread, ip, port); break; } default: break; } } else { - CCLOG("UDP received %d bytes from unknown sender", nread); + CCLOG("UDP received %u bytes from unknown sender", nread); } #endif @@ -57,7 +57,7 @@ void _onRead(uv_udp_t* req, ssize_t nread, uv_buf_t const* buf, struct sockaddr } else if (0 < nread) { // Non-holepunching; it might be more effective in RAM usage to use a threadsafe RingBuff to pass msg to GameThread here, but as long as it's not a performance blocker don't bother optimize here... uint8_t* const ui8Arr = (uint8_t*)malloc(maxUdpPayloadBytes*sizeof(uint8_t)); - memset(ui8Arr, 0, sizeof ui8Arr); + memset(ui8Arr, 0, sizeof(ui8Arr)); for (int i = 0; i < nread; i++) { *(ui8Arr+i) = *(buf->base + i); } @@ -133,16 +133,15 @@ void _onUvSthNewToSend(uv_async_t* handle) { */ uv_mutex_unlock(&sendRingBuffLock); if (NULL != work) { - /* + // [WARNING] If "uv_udp_send" is to be used instead of "uv_udp_try_send", as UvSendThread will always be terminated from GameThread, it's a MUST to use the following heap-alloc form to initialize "uv_udp_send_t* req" such that "_afterSend" is guaranteed to be called, otherwise "int uvRunRet2 = uv_run(l, UV_RUN_DEFAULT);" for UvSendThread would block forever due to residual active handles. - uv_udp_send_t* req = (uv_udp_send_t*)malloc(sizeof uv_udp_send_t); + uv_udp_send_t* req = (uv_udp_send_t*)malloc(sizeof(uv_udp_send_t)); uv_buf_t sendBuffer = uv_buf_init(work->bytes, work->bytesLen); uv_udp_send(req, udpSendSocket, &sendBuffer, 1, (struct sockaddr const*)&(work->peerAddr.sockAddrIn), _afterSend); - */ - uv_buf_t sendBuffer = uv_buf_init(work->bytes, work->bytesLen); - uv_udp_try_send(udpSendSocket, &sendBuffer, 1, (struct sockaddr const*)&(work->peerAddr.sockAddrIn)); + //uv_buf_t sendBuffer = uv_buf_init(work->bytes, work->bytesLen); + //uv_udp_try_send(udpSendSocket, &sendBuffer, 1, (struct sockaddr const*)&(work->peerAddr.sockAddrIn)); #if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) char ip[INET_ADDRSTRLEN]; memset(ip, 0, sizeof ip); @@ -213,7 +212,7 @@ bool DelayNoMore::UdpSession::openUdpSession(int port) { uv_async_init(recvLoop, &uvRecvLoopStopSig, _onUvStopSig); uv_mutex_init(&sendRingBuffLock); - sendRingBuff = new SendRingBuffer(maxBuffedMsgs); + sendRingBuff = new SendRingBuff(maxBuffedMsgs); uv_async_init(sendLoop, &uvSendLoopStopSig, _onUvStopSig); uv_async_init(sendLoop, &uvSendLoopTriggerSig, _onUvSthNewToSend); diff --git a/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.android-studio/app/jni/Android.mk b/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.android-studio/app/jni/Android.mk index 536756f..4af1fdf 100644 --- a/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.android-studio/app/jni/Android.mk +++ b/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.android-studio/app/jni/Android.mk @@ -15,6 +15,7 @@ LOCAL_SRC_FILES := hellojavascript/main.cpp \ ../../../Classes/jsb_module_register.cpp \ ../../../Classes/udp_session.cpp \ ../../../Classes/udp_session_bridge.cpp \ + ../../../Classes/send_ring_buff.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../Classes diff --git a/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.win32/DelayNoMore.vcxproj b/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.win32/DelayNoMore.vcxproj index dbadfd3..c29d7c0 100644 --- a/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.win32/DelayNoMore.vcxproj +++ b/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.win32/DelayNoMore.vcxproj @@ -190,6 +190,7 @@ copy "$(ProjectDir)..\..\..\project.json" "$(OutDir)\" /Y + diff --git a/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.win32/DelayNoMore.vcxproj.filters b/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.win32/DelayNoMore.vcxproj.filters index a09c1ea..a5df7d6 100644 --- a/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.win32/DelayNoMore.vcxproj.filters +++ b/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.win32/DelayNoMore.vcxproj.filters @@ -22,6 +22,9 @@ Classes + + Classes + Classes