本文整理汇总了C++中socket::Connection::spool方法的典型用法代码示例。如果您正苦于以下问题:C++ Connection::spool方法的具体用法?C++ Connection::spool怎么用?C++ Connection::spool使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类socket::Connection
的用法示例。
在下文中一共展示了Connection::spool方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: while
/// Blocks until either the stream encounters a pause mark or the sourceSocket errors.
/// This function is intended to be run after the 'q' command is sent, throwing away superfluous packets.
/// It will time out after 5 seconds, disconnecting the sourceSocket.
void DTSC::Stream::waitForPause(Socket::Connection & sourceSocket) {
bool wasBlocking = sourceSocket.isBlocking();
sourceSocket.setBlocking(false);
//cancel the attempt after 5000 milliseconds
long long int start = Util::getMS();
while (lastType() != DTSC::PAUSEMARK && sourceSocket.connected() && Util::getMS() - start < 5000) {
//we have data? parse it
if (sourceSocket.Received().size()) {
//return value is ignored because we're not interested.
parsePacket(sourceSocket.Received());
}
//still no pause mark? check for more data
if (lastType() != DTSC::PAUSEMARK) {
if (sourceSocket.spool()) {
//more received? attempt to read
//return value is ignored because we're not interested in data packets, just metadata.
parsePacket(sourceSocket.Received());
} else {
//nothing extra to receive? wait a bit and retry
Util::sleep(10);
}
}
}
sourceSocket.setBlocking(wasBlocking);
//if the timeout has passed, close the socket
if (Util::getMS() - start >= 5000) {
sourceSocket.close();
//and optionally print a debug message that this happened
DEBUG_MSG(DLVL_DEVEL, "Timing out while waiting for pause break");
}
}
示例2: main
///\brief Contains the main code for the RAW connector.
///
///Expects a single commandline argument telling it which stream to connect to,
///then outputs the raw stream to stdout.
int main(int argc, char ** argv){
Util::Config conf(argv[0], PACKAGE_VERSION);
JSON::Value capa;
conf.addBasicConnectorOptions(capa);
conf.addOption("stream_name", JSON::fromString("{\"arg_num\":1, \"help\":\"Name of the stream to write to stdout.\"}"));
conf.parseArgs(argc, argv);
if (conf.getBool("json")){
std::cout << "null" << std::endl;
return -1;
}
//connect to the proper stream
Socket::Connection S = Util::Stream::getStream(conf.getString("stream_name"));
S.setBlocking(false);
if ( !S.connected()){
std::cout << "Could not open stream " << conf.getString("stream_name") << std::endl;
return 1;
}
long long int lastStats = 0;
long long int started = Util::epoch();
while (std::cout.good()){
if (S.spool()){
while (S.Received().size()){
std::cout.write(S.Received().get().c_str(), S.Received().get().size());
S.Received().get().clear();
}
}else{
Util::sleep(10); //sleep 10ms if no data
}
unsigned int now = Util::epoch();
if (now != lastStats){
lastStats = now;
std::stringstream st;
st << "S localhost RAW " << (Util::epoch() - started) << " " << S.dataDown() << " " << S.dataUp() << "\n";
S.SendNow(st.str().c_str());
}
}
std::stringstream st;
st << "S localhost RAW " << (Util::epoch() - started) << " " << S.dataDown() << " " << S.dataUp() << "\n";
S.SendNow(st.str().c_str());
S.close();
return 0;
}
示例3: tsConnector
///\brief Main function for the TS Connector
///\param conn A socket describing the connection the client.
///\param streamName The stream to connect to.
///\return The exit code of the connector.
int tsConnector(Socket::Connection conn, std::string streamName, std::string trackIDs){
std::string ToPack;
TS::Packet PackData;
std::string DTMIData;
int PacketNumber = 0;
long long unsigned int TimeStamp = 0;
int ThisNaluSize;
char VideoCounter = 0;
char AudioCounter = 0;
bool WritePesHeader;
bool IsKeyFrame;
bool FirstKeyFrame = true;
bool FirstIDRInKeyFrame;
MP4::AVCC avccbox;
bool haveAvcc = false;
DTSC::Stream Strm;
bool inited = false;
Socket::Connection ss;
while (conn.connected()){
if ( !inited){
ss = Util::Stream::getStream(streamName);
if ( !ss.connected()){
#if DEBUG >= 1
fprintf(stderr, "Could not connect to server!\n");
#endif
conn.close();
break;
}
if(trackIDs == ""){
// no track ids given? Find the first video and first audio track (if available) and use those!
int videoID = -1;
int audioID = -1;
Strm.waitForMeta(ss);
if (Strm.metadata.isMember("tracks")){
for (JSON::ObjIter trackIt = Strm.metadata["tracks"].ObjBegin(); trackIt != Strm.metadata["tracks"].ObjEnd(); trackIt++){
if (audioID == -1 && trackIt->second["type"].asString() == "audio"){
audioID = trackIt->second["trackid"].asInt();
if( trackIDs != ""){
trackIDs += " " + trackIt->second["trackid"].asString();
}else{
trackIDs = trackIt->second["trackid"].asString();
}
}
if (videoID == -1 && trackIt->second["type"].asString() == "video"){
videoID = trackIt->second["trackid"].asInt();
if( trackIDs != ""){
trackIDs += " " + trackIt->second["trackid"].asString();
}else{
trackIDs = trackIt->second["trackid"].asString();
}
}
} // for iterator
} // if isMember("tracks")
} // if trackIDs == ""
std::string cmd = "t " + trackIDs + "\ns 0\np\n";
ss.SendNow( cmd );
inited = true;
}
if (ss.spool()){
while (Strm.parsePacket(ss.Received())){
std::stringstream TSBuf;
Socket::Buffer ToPack;
//write PAT and PMT TS packets
if (PacketNumber == 0){
PackData.DefaultPAT();
TSBuf.write(PackData.ToString(), 188);
PackData.DefaultPMT();
TSBuf.write(PackData.ToString(), 188);
PacketNumber += 2;
}
int PIDno = 0;
char * ContCounter = 0;
if (Strm.lastType() == DTSC::VIDEO){
if ( !haveAvcc){
avccbox.setPayload(Strm.getTrackById(Strm.getPacket()["trackid"].asInt())["init"].asString());
haveAvcc = true;
}
IsKeyFrame = Strm.getPacket().isMember("keyframe");
if (IsKeyFrame){
TimeStamp = (Strm.getPacket()["time"].asInt() * 27000);
}
ToPack.append(avccbox.asAnnexB());
while (Strm.lastData().size() > 4){
//.........这里部分代码省略.........
示例4: Connector_HTTP_Dynamic
/// Main function for Connector_HTTP_Dynamic
int Connector_HTTP_Dynamic(Socket::Connection conn){
std::deque<std::string> FlashBuf;
std::vector<int> Timestamps;
int FlashBufSize = 0;
long long int FlashBufTime = 0;
DTSC::Stream Strm; //Incoming stream buffer.
HTTP::Parser HTTP_R, HTTP_S; //HTTP Receiver en HTTP Sender.
bool ready4data = false; //Set to true when streaming is to begin.
bool pending_manifest = false;
bool receive_marks = false; //when set to true, this stream will ignore keyframes and instead use pause marks
bool inited = false;
Socket::Connection ss( -1);
std::string streamname;
std::string recBuffer = "";
bool wantsVideo = false;
bool wantsAudio = false;
std::string Quality;
int Segment = -1;
long long int ReqFragment = -1;
int temp;
std::string tempStr;
int Flash_RequestPending = 0;
unsigned int lastStats = 0;
conn.setBlocking(false); //do not block on conn.spool() when no data is available
while (conn.connected()){
if (conn.spool() || conn.Received().size()){
//make sure it ends in a \n
if ( *(conn.Received().get().rbegin()) != '\n'){
std::string tmp = conn.Received().get();
conn.Received().get().clear();
if (conn.Received().size()){
conn.Received().get().insert(0, tmp);
}else{
conn.Received().append(tmp);
}
}
if (HTTP_R.Read(conn.Received().get())){
#if DEBUG >= 4
std::cout << "Received request: " << HTTP_R.getUrl() << std::endl;
#endif
conn.setHost(HTTP_R.GetHeader("X-Origin"));
if (HTTP_R.url.find("Manifest") == std::string::npos){
streamname = HTTP_R.url.substr(8, HTTP_R.url.find("/", 8) - 12);
if ( !ss){
ss = Util::Stream::getStream(streamname);
if ( !ss.connected()){
#if DEBUG >= 1
fprintf(stderr, "Could not connect to server!\n");
#endif
ss.close();
HTTP_S.Clean();
HTTP_S.SetBody("No such stream " + streamname + " is available on the system. Please try again.\n");
conn.SendNow(HTTP_S.BuildResponse("404", "Not found"));
ready4data = false;
continue;
}
ss.setBlocking(false);
inited = true;
}
Quality = HTTP_R.url.substr(HTTP_R.url.find("/Q(", 8) + 3);
Quality = Quality.substr(0, Quality.find(")"));
tempStr = HTTP_R.url.substr(HTTP_R.url.find(")/") + 2);
wantsAudio = false;
wantsVideo = false;
if (tempStr[0] == 'A'){
wantsAudio = true;
}
if (tempStr[0] == 'V'){
wantsVideo = true;
}
tempStr = tempStr.substr(tempStr.find("(") + 1);
ReqFragment = atoll(tempStr.substr(0, tempStr.find(")")).c_str());
#if DEBUG >= 4
printf("Quality: %s, Frag %d\n", Quality.c_str(), (ReqFragment / 10000));
#endif
std::stringstream sstream;
sstream << "s " << (ReqFragment / 10000) << "\no \n";
ss.SendNow(sstream.str().c_str());
Flash_RequestPending++;
}else{
streamname = HTTP_R.url.substr(8, HTTP_R.url.find("/", 8) - 12);
if ( !Strm.metadata.isNull()){
HTTP_S.Clean();
HTTP_S.SetHeader("Content-Type", "text/xml");
HTTP_S.SetHeader("Cache-Control", "no-cache");
if (Strm.metadata.isMember("length")){
receive_marks = true;
}
std::string manifest = BuildManifest(streamname, Strm.metadata);
HTTP_S.SetBody(manifest);
conn.SendNow(HTTP_S.BuildResponse("200", "OK"));
#if DEBUG >= 3
printf("Sent manifest\n");
#endif
//.........这里部分代码省略.........
示例5: dynamicConnector
///\brief Main function for the HTTP Dynamic Connector
///\param conn A socket describing the connection the client.
///\return The exit code of the connector.
int dynamicConnector(Socket::Connection conn){
std::deque<std::string> FlashBuf;
int FlashBufSize = 0;
long long int FlashBufTime = 0;
FLV::Tag tmp; //temporary tag
DTSC::Stream Strm; //Incoming stream buffer.
HTTP::Parser HTTP_R, HTTP_S; //HTTP Receiver en HTTP Sender.
Socket::Connection ss( -1);
std::string streamname;
std::string recBuffer = "";
std::string Quality;
int Segment = -1;
int ReqFragment = -1;
unsigned int lastStats = 0;
conn.setBlocking(false); //do not block on conn.spool() when no data is available
while (conn.connected()){
if (conn.spool() || conn.Received().size()){
//make sure it ends in a \n
if ( *(conn.Received().get().rbegin()) != '\n'){
std::string tmp = conn.Received().get();
conn.Received().get().clear();
if (conn.Received().size()){
conn.Received().get().insert(0, tmp);
}else{
conn.Received().append(tmp);
}
}
if (HTTP_R.Read(conn.Received().get())){
#if DEBUG >= 5
std::cout << "Received request: " << HTTP_R.getUrl() << std::endl;
#endif
conn.setHost(HTTP_R.GetHeader("X-Origin"));
streamname = HTTP_R.GetHeader("X-Stream");
if ( !ss){
ss = Util::Stream::getStream(streamname);
if ( !ss.connected()){
HTTP_S.Clean();
HTTP_S.SetBody("No such stream is available on the system. Please try again.\n");
conn.SendNow(HTTP_S.BuildResponse("404", "Not found"));
continue;
}
ss.setBlocking(false);
//make sure metadata is received
while ( !Strm.metadata && ss.connected()){
if (ss.spool()){
while (Strm.parsePacket(ss.Received())){
//do nothing
}
}
}
}
if (HTTP_R.url.find(".abst") != std::string::npos){
HTTP_S.Clean();
HTTP_S.SetBody(dynamicBootstrap(streamname, Strm.metadata));
HTTP_S.SetHeader("Content-Type", "binary/octet");
HTTP_S.SetHeader("Cache-Control", "no-cache");
conn.SendNow(HTTP_S.BuildResponse("200", "OK"));
HTTP_R.Clean(); //clean for any possible next requests
continue;
}
if (HTTP_R.url.find("f4m") == std::string::npos){
Quality = HTTP_R.url.substr(HTTP_R.url.find("/", 10) + 1);
Quality = Quality.substr(0, Quality.find("Seg"));
int temp;
temp = HTTP_R.url.find("Seg") + 3;
Segment = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find("-", temp) - temp).c_str());
temp = HTTP_R.url.find("Frag") + 4;
ReqFragment = atoi(HTTP_R.url.substr(temp).c_str());
#if DEBUG >= 5
printf("Quality: %s, Seg %d Frag %d\n", Quality.c_str(), Segment, ReqFragment);
#endif
if (Strm.metadata.isMember("live")){
int seekable = Strm.canSeekFrame(ReqFragment);
if (seekable == 0){
// iff the fragment in question is available, check if the next is available too
seekable = Strm.canSeekFrame(ReqFragment + 1);
}
if (seekable < 0){
HTTP_S.Clean();
HTTP_S.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
conn.SendNow(HTTP_S.BuildResponse("412", "Fragment out of range"));
HTTP_R.Clean(); //clean for any possible next requests
std::cout << "Fragment @ F" << ReqFragment << " too old (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
continue;
}
if (seekable > 0){
HTTP_S.Clean();
HTTP_S.SetBody("Proxy, re-request this in a second or two.\n");
conn.SendNow(HTTP_S.BuildResponse("208", "Ask again later"));
HTTP_R.Clean(); //clean for any possible next requests
std::cout << "Fragment @ F" << ReqFragment << " not available yet (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
continue;
}
//.........这里部分代码省略.........
示例6: tsConnector
///\brief Main function for the TS Connector
///\param conn A socket describing the connection the client.
///\param streamName The stream to connect to.
///\return The exit code of the connector.
int tsConnector(Socket::Connection conn, std::string streamName){
std::string ToPack;
TS::Packet PackData;
std::string DTMIData;
int PacketNumber = 0;
long long unsigned int TimeStamp = 0;
int ThisNaluSize;
char VideoCounter = 0;
char AudioCounter = 0;
bool WritePesHeader;
bool IsKeyFrame;
bool FirstKeyFrame = true;
bool FirstIDRInKeyFrame;
MP4::AVCC avccbox;
bool haveAvcc = false;
DTSC::Stream Strm;
bool inited = false;
Socket::Connection ss;
while (conn.connected()){
if ( !inited){
ss = Util::Stream::getStream(streamName);
if ( !ss.connected()){
#if DEBUG >= 1
fprintf(stderr, "Could not connect to server!\n");
#endif
conn.close();
break;
}
ss.SendNow("p\n");
inited = true;
}
if (ss.spool()){
while (Strm.parsePacket(ss.Received())){
if ( !haveAvcc){
avccbox.setPayload(Strm.metadata["video"]["init"].asString());
haveAvcc = true;
}
std::stringstream TSBuf;
Socket::Buffer ToPack;
//write PAT and PMT TS packets
if (PacketNumber == 0){
PackData.DefaultPAT();
TSBuf.write(PackData.ToString(), 188);
PackData.DefaultPMT();
TSBuf.write(PackData.ToString(), 188);
PacketNumber += 2;
}
int PIDno = 0;
char * ContCounter = 0;
if (Strm.lastType() == DTSC::VIDEO){
IsKeyFrame = Strm.getPacket(0).isMember("keyframe");
if (IsKeyFrame){
TimeStamp = (Strm.getPacket(0)["time"].asInt() * 27000);
}
ToPack.append(avccbox.asAnnexB());
while (Strm.lastData().size()){
ThisNaluSize = (Strm.lastData()[0] << 24) + (Strm.lastData()[1] << 16) + (Strm.lastData()[2] << 8) + Strm.lastData()[3];
Strm.lastData().replace(0, 4, TS::NalHeader, 4);
if (ThisNaluSize + 4 == Strm.lastData().size()){
ToPack.append(Strm.lastData());
break;
}else{
ToPack.append(Strm.lastData().c_str(), ThisNaluSize + 4);
Strm.lastData().erase(0, ThisNaluSize + 4);
}
}
ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket(0)["time"].asInt() * 90));
PIDno = 0x100;
ContCounter = &VideoCounter;
}else if (Strm.lastType() == DTSC::AUDIO){
ToPack.append(TS::GetAudioHeader(Strm.lastData().size(), Strm.metadata["audio"]["init"].asString()));
ToPack.append(Strm.lastData());
ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket(0)["time"].asInt() * 90));
PIDno = 0x101;
ContCounter = &AudioCounter;
}
//initial packet
PackData.Clear();
PackData.PID(PIDno);
PackData.ContinuityCounter(( *ContCounter)++);
PackData.UnitStart(1);
if (IsKeyFrame){
PackData.RandomAccess(1);
PackData.PCR(TimeStamp);
}
unsigned int toSend = PackData.AddStuffing(ToPack.bytes(184));
std::string gonnaSend = ToPack.remove(toSend);
PackData.FillFree(gonnaSend);
TSBuf.write(PackData.ToString(), 188);
PacketNumber++;
//rest of packets
//.........这里部分代码省略.........
示例7: SendResponse
/// After receiving a header with this object, this function call will:
/// - Forward the headers to the 'to' Socket::Connection.
/// - Retrieve all the body from the 'from' Socket::Connection.
/// - Forward those contents as-is to the 'to' Socket::Connection.
/// It blocks until completed or either of the connections reaches an error state.
void HTTP::Parser::Proxy(Socket::Connection & from, Socket::Connection & to) {
SendResponse(url, method, to);
if (getChunks) {
unsigned int proxyingChunk = 0;
while (to.connected() && from.connected()) {
if ((from.Received().size() && (from.Received().size() > 1 || *(from.Received().get().rbegin()) == '\n')) || from.spool()) {
if (proxyingChunk) {
while (proxyingChunk && from.Received().size()) {
unsigned int toappend = from.Received().get().size();
if (toappend > proxyingChunk) {
toappend = proxyingChunk;
to.SendNow(from.Received().get().c_str(), toappend);
from.Received().get().erase(0, toappend);
} else {
to.SendNow(from.Received().get());
from.Received().get().clear();
}
proxyingChunk -= toappend;
}
} else {
//Make sure the received data ends in a newline (\n).
if (*(from.Received().get().rbegin()) != '\n') {
if (from.Received().size() > 1) {
//make a copy of the first part
std::string tmp = from.Received().get();
//clear the first part, wiping it from the partlist
from.Received().get().clear();
from.Received().size();
//take the now first (was second) part, insert the stored part in front of it
from.Received().get().insert(0, tmp);
} else {
Util::sleep(100);
}
if (*(from.Received().get().rbegin()) != '\n') {
continue;
}
}
//forward the size and any empty lines
to.SendNow(from.Received().get());
std::string tmpA = from.Received().get().substr(0, from.Received().get().size() - 1);
while (tmpA.find('\r') != std::string::npos) {
tmpA.erase(tmpA.find('\r'));
}
unsigned int chunkLen = 0;
if (!tmpA.empty()) {
for (unsigned int i = 0; i < tmpA.size(); ++i) {
chunkLen = (chunkLen << 4) | unhex(tmpA[i]);
}
if (chunkLen == 0) {
getChunks = false;
to.SendNow("\r\n", 2);
return;
}
proxyingChunk = chunkLen;
}
from.Received().get().clear();
}
} else {
Util::sleep(100);
}
}
} else {
unsigned int bodyLen = length;
while (bodyLen > 0 && to.connected() && from.connected()) {
if (from.Received().size() || from.spool()) {
if (from.Received().get().size() <= bodyLen) {
to.SendNow(from.Received().get());
bodyLen -= from.Received().get().size();
from.Received().get().clear();
} else {
to.SendNow(from.Received().get().c_str(), bodyLen);
from.Received().get().erase(0, bodyLen);
bodyLen = 0;
}
} else {
Util::sleep(100);
}
}
}
}
示例8: rtmpConnector
///\brief Main function for the RTMP Connector
///\param conn A socket describing the connection the client.
///\return The exit code of the connector.
int rtmpConnector(Socket::Connection conn){
Socket = conn;
Socket.setBlocking(false);
FLV::Tag tag, init_tag;
DTSC::Stream Strm;
while ( !Socket.Received().available(1537) && Socket.connected()){
Socket.spool();
Util::sleep(5);
}
RTMPStream::handshake_in = Socket.Received().remove(1537);
RTMPStream::rec_cnt += 1537;
if (RTMPStream::doHandshake()){
Socket.SendNow(RTMPStream::handshake_out);
while ( !Socket.Received().available(1536) && Socket.connected()){
Socket.spool();
Util::sleep(5);
}
Socket.Received().remove(1536);
RTMPStream::rec_cnt += 1536;
#if DEBUG >= 5
fprintf(stderr, "Handshake succcess!\n");
#endif
}else{
#if DEBUG >= 5
fprintf(stderr, "Handshake fail!\n");
#endif
return 0;
}
unsigned int lastStats = 0;
bool firsttime = true;
while (Socket.connected()){
if (Socket.spool() || firsttime){
parseChunk(Socket.Received());
firsttime = false;
}else{
Util::sleep(1); //sleep 1ms to prevent high CPU usage
}
if (ready4data){
if ( !inited){
//we are ready, connect the socket!
ss = Util::Stream::getStream(streamName);
if ( !ss.connected()){
#if DEBUG >= 1
fprintf(stderr, "Could not connect to server!\n");
#endif
Socket.close(); //disconnect user
break;
}
ss.setBlocking(false);
Strm.waitForMeta(ss);
//find first audio and video tracks
for (JSON::ObjIter objIt = Strm.metadata["tracks"].ObjBegin(); objIt != Strm.metadata["tracks"].ObjEnd(); objIt++){
if (videoID == -1 && objIt->second["type"].asStringRef() == "video"){
videoID = objIt->second["trackid"].asInt();
}
if (audioID == -1 && objIt->second["type"].asStringRef() == "audio"){
audioID = objIt->second["trackid"].asInt();
}
}
//select the tracks and play
std::stringstream cmd;
cmd << "t";
if (videoID != -1){
cmd << " " << videoID;
}
if (audioID != -1){
cmd << " " << audioID;
}
cmd << "\np\n";
ss.SendNow(cmd.str().c_str());
inited = true;
}
if (inited && !noStats){
long long int now = Util::epoch();
if (now != lastStats){
lastStats = now;
ss.SendNow(Socket.getStats("RTMP"));
}
}
if (ss.spool()){
while (Strm.parsePacket(ss.Received())){
if (playTransaction != -1){
//send a status reply
AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
amfreply.addContent(AMF::Object("", "onStatus")); //status reply
amfreply.addContent(AMF::Object("", (double)playTransaction)); //same transaction ID
amfreply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //null - command info
amfreply.addContent(AMF::Object("")); //info
amfreply.getContentP(3)->addContent(AMF::Object("level", "status"));
amfreply.getContentP(3)->addContent(AMF::Object("code", "NetStream.Play.Reset"));
amfreply.getContentP(3)->addContent(AMF::Object("description", "Playing and resetting..."));
amfreply.getContentP(3)->addContent(AMF::Object("details", "DDV"));
amfreply.getContentP(3)->addContent(AMF::Object("clientid", (double)1337));
//.........这里部分代码省略.........