bool LLBC_Session::OnRecved(LLBC_MessageBlock *block) { std::vector<LLBC_Packet *> packets; #if LLBC_CFG_COMM_USE_FULL_STACK if (_protoStack->Recv(block, packets) != LLBC_RTN_OK) #else if (_protoStack->RecvRaw(block, packets) != LLBC_RTN_OK) #endif { this->OnClose(); return false; } LLBC_Packet *packet; for (size_t i = 0; i < packets.size(); i++) { packet = packets[i]; packet->SetSessionId(_id); packet->SetLocalAddr(_socket->GetLocalAddress()); packet->SetPeerAddr(_socket->GetPeerAddress()); _svc->Push(LLBC_SvcEvUtil::BuildDataArrivalEv(packet)); } return true; }
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; }
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; }
void LLBC_PacketHeaderParts::SetPartToPacket(int serialNo, const _Part &part, LLBC_Packet &packet) { switch (part.type) { case _PartTypes::SInt32Type: packet.SetHeaderPartVal(serialNo, static_cast<sint32>(part.value.i64Val)); break; case _PartTypes::UInt32Type: packet.SetHeaderPartVal(serialNo, static_cast<uint32>(part.value.i64Val)); break; case _PartTypes::SInt16Type: packet.SetHeaderPartVal(serialNo, static_cast<sint16>(part.value.i64Val)); break; case _PartTypes::UInt16Type: packet.SetHeaderPartVal(serialNo, static_cast<uint16>(part.value.i64Val)); break; case _PartTypes::SInt8Type: packet.SetHeaderPartVal(serialNo, static_cast<sint8>(part.value.i64Val)); break; case _PartTypes::UInt8Type: packet.SetHeaderPartVal(serialNo, static_cast<uint8>(part.value.i64Val)); break; case _PartTypes::SInt64Type: packet.SetHeaderPartVal(serialNo, part.value.i64Val); break; case _PartTypes::UInt64Type: packet.SetHeaderPartVal(serialNo, static_cast<uint64>(part.value.i64Val)); break; case _PartTypes::FloatType: packet.SetHeaderPartVal(serialNo, *reinterpret_cast<const float *>(&part.value.i64Val)); break; case _PartTypes::DoubleType: packet.SetHeaderPartVal(serialNo, *reinterpret_cast<const double *>(&part.value.i64Val)); break; case _PartTypes::StrType: packet.SetHeaderPartVal(serialNo, *part.value.strVal); break; case _PartTypes::BytesType: packet.SetHeaderPartVal(serialNo, part.value.bytesVal->GetDataStartWithReadPos(), part.value.bytesVal->GetReadableSize()); break; default: ASSERT(false && "llbc library internal error, Unknown packet header part type: %d"); break; } }
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_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; }