LLBC_MessageBlock *LLBC_SvcEvUtil::BuildDataArrivalEv(LLBC_Packet *packet) { typedef LLBC_SvcEv_DataArrival _Ev; _Ev *ev = LLBC_New(_Ev); ev->packet = packet; return __CreateEvBlock(ev); }
LLBC_MessageBlock *LLBC_SvcEvUtil::BuildFireEvEv(LLBC_Event *ev) { typedef LLBC_SvcEv_FireEv _Ev; _Ev *e = LLBC_New(_Ev); e->ev = ev; return __CreateEvBlock(e); }
LLBC_MessageBlock *LLBC_SvcEvUtil::BuildSessionDestroyEv(int sessionId) { typedef LLBC_SvcEv_SessionDestroy _Ev; _Ev *ev = LLBC_New(_Ev); ev->sessionId = sessionId; return __CreateEvBlock(ev); }
LLBC_MessageBlock *LLBC_SvcEvUtil::BuildUnsubscribeEvEv(int id, const LLBC_String &stub) { typedef LLBC_SvcEv_UnsubscribeEv _Ev; _Ev *ev = LLBC_New(_Ev); ev->id = id; ev->stub.append(stub); return __CreateEvBlock(ev); }
void LLBC_IocpPoller::HandleEv_AsyncConn(LLBC_PollerEvent &ev) { bool succeed = true; LLBC_String reason = "Success"; do { LLBC_SocketHandle handle = LLBC_CreateTcpSocketEx(); if (handle == LLBC_INVALID_SOCKET_HANDLE) { succeed = false; reason = LLBC_FormatLastError(); break; } LLBC_Socket *socket = LLBC_New1(LLBC_Socket, handle); socket->SetNonBlocking(); socket->SetPollerType(LLBC_PollerType::IocpPoller); if (socket->AttachToIocp(_iocp) != LLBC_OK) { LLBC_Delete(socket); succeed = false; reason = LLBC_FormatLastError(); break; } LLBC_POverlapped ol = LLBC_New(LLBC_Overlapped); ol->opcode = LLBC_OverlappedOpcode::Connect; ol->sock = handle; if (socket->ConnectEx(ev.peerAddr, ol) != LLBC_OK && LLBC_GetLastError() != LLBC_ERROR_PENDING) { LLBC_Delete(ol); LLBC_Delete(socket); succeed = false; reason = LLBC_FormatLastError(); break; } socket->InsertOverlapped(ol); LLBC_AsyncConnInfo asyncInfo; asyncInfo.socket = socket; asyncInfo.peerAddr = ev.peerAddr; asyncInfo.sessionId = ev.sessionId; _connecting.insert(std::make_pair(handle, asyncInfo)); } while (false); if (!succeed) _svc->Push(LLBC_SvcEvUtil:: BuildAsyncConnResultEv(succeed, reason, ev.peerAddr)); }
LLBC_MessageBlock *LLBC_SvcEvUtil::BuildSubscribeEvEv(int id, const LLBC_String &stub, LLBC_IDelegate1<LLBC_Event *> *deleg) { typedef LLBC_SvcEv_SubscribeEv _Ev; _Ev *ev = LLBC_New(_Ev); ev->id = id; ev->stub.append(stub); ev->deleg = deleg; return __CreateEvBlock(ev); }
LLBC_MessageBlock *LLBC_SvcEvUtil::BuildAsyncConnResultEv(bool connected, const LLBC_String &reason, const LLBC_SockAddr_IN &peer) { typedef LLBC_SvcEv_AsyncConn _Ev; _Ev *ev = LLBC_New(_Ev); ev->connected = connected; ev->reason.append(reason); ev->peer = peer; return __CreateEvBlock(ev); }
int pyllbc_Service::Send(int sessionId, int opcode, PyObject *data, int status, PyObject *parts) { // Started check. if (UNLIKELY(!this->IsStarted())) { pyllbc_SetError("service not start"); return LLBC_RTN_FAILED; } // Build parts, if exists. LLBC_PacketHeaderParts *cLayerParts = NULL; if (parts && _llbcSvcType != LLBC_IService::Raw) { if (!(cLayerParts = this->BuildCLayerParts(parts))) return LLBC_RTN_FAILED; } // Serialize python layer 'data' object to stream. LLBC_Stream stream; const int ret = this->SerializePyObj2Stream(data, stream); if (UNLIKELY(ret != LLBC_RTN_OK)) { LLBC_XDelete(cLayerParts); return LLBC_RTN_FAILED; } // Build packet & send. LLBC_Packet *packet = LLBC_New(LLBC_Packet); packet->Write(stream.GetBuf(), stream.GetPos()); packet->SetSessionId(sessionId); if (_llbcSvcType != LLBC_IService::Raw) { packet->SetOpcode(opcode); packet->SetStatus(status); if (cLayerParts) { cLayerParts->SetToPacket(*packet); LLBC_Delete(cLayerParts); } } if (UNLIKELY(_llbcSvc->Send(packet) == LLBC_RTN_FAILED)) { pyllbc_TransferLLBCError(__FILE__, __LINE__); return LLBC_RTN_FAILED; } return LLBC_RTN_OK; }
LLBC_MessageBlock *LLBC_SvcEvUtil::BuildProtoReportEv(int sessionId, int layer, int level, const LLBC_String &report) { typedef LLBC_SvcEv_ProtoReport _Ev; _Ev *ev = LLBC_New(_Ev); ev->sessionId = sessionId; ev->layer = layer; ev->level = level; ev->report.append(report); return __CreateEvBlock(ev); }
int TestCase_Comm_Event::Run(int argc, char *argv[]) { std::cout <<"Core/Event component testcase..." <<std::endl; // We create a service to test. LLBC_IService *svc = LLBC_IService::Create(LLBC_IService::Normal); svc->RegisterFacade(LLBC_New(EventTestFacade)); svc->Start(); std::cout <<"Press any key to continue..." <<std::endl; getchar(); delete svc; return LLBC_OK; }
LLBC_MessageBlock *LLBC_SvcEvUtil::BuildSessionCreateEv(const LLBC_SockAddr_IN &local, const LLBC_SockAddr_IN &peer, bool isListen, int sessionId, LLBC_SocketHandle handle) { typedef LLBC_SvcEv_SessionCreate _Ev; _Ev *ev = LLBC_New(_Ev); ev->isListen = isListen; ev->sessionId = sessionId; ev->local = local; ev->peer = peer; ev->handle = handle; return __CreateEvBlock(ev); }
int TestCase_Comm_LazyTask::Run(int argc, char *argv[]) { LLBC_PrintLine("service/lazy task test:"); LLBC_IService *svc = LLBC_IService::Create(LLBC_IService::Normal); LazyClass *taskObj = LLBC_New(LazyClass); svc->Post(taskObj, &LazyClass::BeforeRun); svc->Start(); LLBC_PrintLine("Press any key to exit..."); getchar(); LLBC_Delete(svc); LLBC_Delete(taskObj); return LLBC_OK; }
int pyllbc_PackLemma_Dict::Process(Symbol ch, Symbol nextCh) { // State logic. if (_state == Base::Done && _state == Base::Error) { pyllbc_SetError("dict-lemma state is done or error, could not continuing to parse format string"); return LLBC_RTN_FAILED; } if (_state == Base::Begin) { if (ch != Base::DictBegin) { _state = Base::Error; pyllbc_SetError("dict-lemma expect dict begin character'{', got %c", ch); return LLBC_RTN_FAILED; } _state = Base::Accepting; _str.append(1, static_cast<char>(ch)); return LLBC_RTN_OK; } // Key-Word separator & dict close character('}') logic. if (ch == Base::DictKWSep) { if (!_keyLemma) { _state = Base::Error; pyllbc_SetError("dict-lemma expect key lemma, got key-word separator"); return LLBC_RTN_FAILED; } else if (_valueLemma) { _state = Base::Error; pyllbc_SetError("dict-lemma expect dict close character '}', got key-word separator"); return LLBC_RTN_FAILED; } _gotKwSep = true; _str.append(1, static_cast<char>(ch)); return LLBC_RTN_OK; } else if (ch == Base::DictEnd) { if (!_keyLemma || !_valueLemma) { _state = Base::Error; pyllbc_SetError("dict-lemma not done, but got dict close character '}'"); return LLBC_RTN_FAILED; } _state = Base::Done; _str.append(1, static_cast<char>(ch)); return LLBC_RTN_OK; } const SymbolGroup &raw = GroupedSymbol::Raw(); if (raw.find(ch) == raw.end()) { _state = Base::Error; pyllbc_SetError("dict-lemma could direct process non-raw type format character: %c", ch); return LLBC_RTN_FAILED; } Base *lemma = LLBC_New(pyllbc_PackLemma_Raw); if (lemma->Process(ch) != LLBC_RTN_OK) { delete lemma; _state = Base::Error; return LLBC_RTN_FAILED; } if (this->Process(lemma) != LLBC_RTN_OK) { delete lemma; return LLBC_RTN_FAILED; } return LLBC_RTN_OK; }
int TestCase_Comm_SendBytes::Run(int argc, char *argv[]) { LLBC_PrintLine("Servie send bytes test:"); if (argc < 5) { LLBC_PrintLine("argument error, eg: ./a [client/server] [normal/raw] ip port"); return LLBC_FAILED; } FetchArgs(argc, argv); LLBC_IService *svc = LLBC_IService::Create(_svcType); TestFacade *facade = LLBC_New(TestFacade); svc->RegisterFacade(facade); svc->Subscribe(OPCODE, facade, &TestFacade::OnRecv); int sid = 0; if (_asClient) { sid = svc->Connect(_runIp.c_str(), _runPort); if (sid == 0) { LLBC_FilePrintLine(stderr, "connect to %s:%d failed, err: %s", _runIp.c_str(), _runPort, LLBC_FormatLastError()); LLBC_Delete(svc); return LLBC_FAILED; } LLBC_PrintLine("server connect to %s:%d success", _runIp.c_str(), _runPort); } else { sid = svc->Listen(_runIp.c_str(), _runPort); if (sid == 0) { LLBC_FilePrintLine(stderr, "failed to listen on %s:%d, err: %s", _runIp.c_str(), _runPort, LLBC_FormatLastError()); LLBC_Delete(svc); return LLBC_FAILED; } LLBC_PrintLine("server listen on %s:%d", _runIp.c_str(), _runPort); } svc->Start(); if (_asClient) { LLBC_Packet *pkt = LLBC_New(LLBC_Packet); pkt->SetHeader(sid, OPCODE, 0); pkt->Write("Hello, world"); pkt->Write(0); svc->Send(pkt); } LLBC_PrintLine("Press any key to continue..."); getchar(); LLBC_Delete(svc); return LLBC_OK; }
#include "pyllbc/comm/PyService.h" namespace { typedef pyllbc_Service This; void ResetMainloopFlag(void *flagPtr) { bool *flag = reinterpret_cast<bool *>(flagPtr); *flag = false; } } int pyllbc_Service::_maxLLBCSvcId = 0; PyObject *pyllbc_Service::_streamCls = NULL; pyllbc_ErrorHooker *pyllbc_Service::_errHooker = LLBC_New(pyllbc_ErrorHooker); pyllbc_Service::pyllbc_Service(LLBC_IService::Type type, PyObject *pySvc) : _llbcSvc(NULL) , _llbcSvcType(type) , _pySvc(pySvc) , _inMainloop() , _cppFacade(NULL) , _facades() , _handlers() , _preHandlers() #if LLBC_CFG_COMM_ENABLE_UNIFY_PRESUBSCRIBE
LLBC_PacketHeaderParts *pyllbc_Service::BuildCLayerParts(PyObject *pyLayerParts) { // Python layer parts(dict type) convert rules describe: // python type c++ type // -------------------------- // int/long/bool --> sint64 // float4/8 --> float/double // str/bytearray --> LLBC_String if (!PyDict_Check(pyLayerParts)) { pyllbc_SetError("parts instance not dict type"); return NULL; } LLBC_PacketHeaderParts *cLayerParts = LLBC_New(LLBC_PacketHeaderParts); Py_ssize_t pos = 0; PyObject *key, *value; while (PyDict_Next(pyLayerParts, &pos, &key, &value)) // key & value are borrowed. { const int serialNo = static_cast<int>(PyInt_AsLong(key)); if (UNLIKELY(serialNo == -1 && PyErr_Occurred())) { pyllbc_TransferPyError("When fetch header part serial no"); LLBC_Delete(cLayerParts); return NULL; } // Value type check order: // int-> // str-> // float-> // long-> // bool-> // bytearray-> // other objects if (PyInt_CheckExact(value)) { const sint64 cValue = PyInt_AS_LONG(value); cLayerParts->SetPart<sint64>(serialNo, cValue); } else if (PyString_CheckExact(value)) { char *strBeg; Py_ssize_t strLen; if (UNLIKELY(PyString_AsStringAndSize(value, &strBeg, &strLen) == -1)) { pyllbc_TransferPyError("When fetch header part value"); LLBC_Delete(cLayerParts); return NULL; } cLayerParts->SetPart(serialNo, strBeg, strLen); } else if (PyFloat_CheckExact(value)) { const double cValue = PyFloat_AS_DOUBLE(value); cLayerParts->SetPart<double>(serialNo, cValue); } else if (PyLong_CheckExact(value)) { const sint64 cValue = PyLong_AsLongLong(value); cLayerParts->SetPart<sint64>(serialNo, cValue); } else if (PyBool_Check(value)) { const int pyBoolCheck = PyObject_IsTrue(value); if (UNLIKELY(pyBoolCheck == -1)) { pyllbc_TransferPyError("when fetch header part value"); LLBC_Delete(cLayerParts); return NULL; } cLayerParts->SetPart<uint8>(serialNo, pyBoolCheck); } else if (PyByteArray_CheckExact(value)) { char *bytesBeg = PyByteArray_AS_STRING(value); Py_ssize_t bytesLen = PyByteArray_GET_SIZE(value); cLayerParts->SetPart(serialNo, bytesBeg, bytesLen); } else // Other types, we simple get the object string representations. { LLBC_String strRepr = pyllbc_ObjUtil::GetObjStr(value); if (UNLIKELY(strRepr.empty() && PyErr_Occurred())) { LLBC_Delete(cLayerParts); return NULL; } cLayerParts->SetPart(serialNo, strRepr.data(), strRepr.size()); } } return cLayerParts; }
void TestCase_Comm_PacketHeaderParts::TestSetToPacket() { LLBC_PrintLine("Test SetToPacket() method:"); //! First, We must design packet header format. LLBC_PrintLine(" Fristly, we design packet header format."); LLBC_PacketHeaderDesc *headerDesc = LLBC_New(LLBC_PacketHeaderDesc); int serialNo = 0; headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(sint8)).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(uint8)).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(sint16)).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(uint16)).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(sint32)) .SetIsLenPart(true).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(uint32)) .SetIsOpcodePart(true).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(sint64)).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(uint64)).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(float)).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(sizeof(double)).Done(); headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(13).Done(); // "Hello World!"\0 headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(19).Done(); // "Hello std::string!"\0 headerDesc->AddPartDesc() .SetSerialNo(serialNo++).SetPartLen(19).Done(); // "Hello LLBC_String!"\0 LLBC_PrintLine(" Design packet header done, header length: %lu", headerDesc->GetHeaderLen()); // Set header format describe to llbc framework. LLBC_Print(" Set to llbc framework..."); LLBC_IService::SetPacketHeaderDesc(headerDesc); LLBC_PrintLine("Done!"); // Set header value to packet. LLBC_Print("Set the header parts to packet..."); LLBC_Packet packet; _parts.SetToPacket(packet); LLBC_PrintLine("Done!"); // Fetch from packet. LLBC_PrintLine("Fetch values from packet."); serialNo = 0; LLBC_PrintLine(" serial %d: %c", serialNo, packet.GetHeaderPartAsSInt8(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %d", serialNo, packet.GetHeaderPartAsUInt8(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %d", serialNo, packet.GetHeaderPartAsSInt16(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %u", serialNo, packet.GetHeaderPartAsUInt16(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %d", serialNo, packet.GetHeaderPartAsSInt32(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %u", serialNo, packet.GetHeaderPartAsUInt32(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %lld", serialNo, packet.GetHeaderPartAsSInt64(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %llu", serialNo, packet.GetHeaderPartAsUInt64(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %f", serialNo, packet.GetHeaderPartAsFloat(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %f", serialNo, packet.GetHeaderPartAsDouble(serialNo)), serialNo++; LLBC_PrintLine(" serial %d: %s", serialNo, packet.GetHeaderPartAsStr(serialNo).c_str()), serialNo++; // "Hello World!" LLBC_PrintLine(" serial %d: %s", serialNo, packet.GetHeaderPartAsStr(serialNo).c_str()), serialNo++; // "Hello std::string!" LLBC_PrintLine(" serial %d: %s", serialNo, packet.GetHeaderPartAsStr(serialNo).c_str()), serialNo++; // "Hello LLBC_String!" LLBC_PrintLine(" Fetch Done!"); }
int TestCase_Comm_Svc::Run(int argc, char *argv[]) { LLBC_PrintLine("Server/Client test:"); if (argc < 5) { LLBC_PrintLine("argument error, eg: ./a [client/server] [normal/raw] ip port"); return -1; } // Parse arguments. const char *ip = argv[3]; const int port = LLBC_Str2Int32(argv[4]); const bool asClient = LLBC_String(argv[1]) == "client" ? true : false; LLBC_IService::Type svcType = LLBC_String(argv[2]) == "normal" ? LLBC_IService::Normal : LLBC_IService::Raw; LLBC_PrintLine("Will start %s type service, service type: %s", asClient ? "CLIENT" : "SERVER", svcType == LLBC_IService::Normal ? "Normal" : "Raw"); // Create service LLBC_IService *svc = LLBC_IService::Create(svcType); TestFacade *facade = LLBC_New(TestFacade); svc->RegisterFacade(facade); svc->Subscribe(OPCODE, facade, &TestFacade::OnDataArrival); svc->SuppressCoderNotFoundWarning(); svc->Start(2); // Connect to server / Create listen session to wait client connect. int sessionId; if (!asClient) { LLBC_PrintLine("Will listening in %s:%d", ip, port); if ((sessionId = svc->Listen(ip, port)) == 0) { LLBC_PrintLine("Create session failed, reason: %s", LLBC_FormatLastError()); LLBC_Delete(svc); return -1; } } else { // Client service, we create some clients to test service. int clientCount; const int pollerType = LLBC_PollerType::Str2Type(LLBC_CFG_COMM_POLLER_MODEL); if (pollerType == LLBC_PollerType::SelectPoller) clientCount = 50; else clientCount = 1024; LLBC_PrintLine("Create %d clients to test", clientCount); for (int i = 0; i < clientCount; i++) { const int sessionId = svc->Connect(ip, port); const int dataSize = 4096; char *data = LLBC_Malloc(char, dataSize); ::memset(data, 1, dataSize); LLBC_Packet *packet = LLBC_New(LLBC_Packet); packet->SetHeader(sessionId, OPCODE, 0); packet->Write(data, dataSize); LLBC_Free(data); svc->Send(packet); // Test unhandled packet(unsubscribe opcode). LLBC_Packet *unhandledPacket = LLBC_New(LLBC_Packet); unhandledPacket->SetHeader(sessionId, OPCODE + 10000, 0); unhandledPacket->Write("Hello World", 12); svc->Send(unhandledPacket); } } LLBC_PrintLine("Press any key to continue..."); getchar(); return 0; }
__LLBC_NS_BEGIN LLBC_SamplerGroup::LLBC_SamplerGroup() : _samplers(LLBC_New(_SamplerMap)) { }