108 #pragma pack(push, 1)   124         memset( 
this, 0, 
sizeof(*
this) );
   142         memset( 
this, 0, 
sizeof(*
this) );
   145     template < 
typename _Ty >
   148         return reinterpret_cast<_Ty*
>( 
this + 1 );
   153 #pragma pack(push, 2)   162         memset( 
this, 0, 
sizeof(*
this) );
   165     template < 
typename _Ty >
   168         return reinterpret_cast<_Ty*
>( 
this + 1 );
   179         memset( 
this, 0, 
sizeof(*
this) );
   182     template < 
typename _Ty >
   185         return reinterpret_cast<_Ty*
>( 
this + 1 );
   197         memset( 
this, 0, 
sizeof(*
this) );
   200     template < 
typename _Ty >
   203         return reinterpret_cast<_Ty*
>( 
this + 1 );
   214         memset( 
this, 0, 
sizeof(*
this) );
   217     template < 
typename _Ty >
   220         return reinterpret_cast<_Ty*
>( 
this + 1 );
   232         memset( 
this, 0, 
sizeof(*
this) );
   235     template < 
typename _Ty >
   238         return reinterpret_cast<_Ty*
>( 
this + 1 );
   246     template < 
typename _Ty >
   249         return reinterpret_cast<_Ty*
>( 
this + 1 );
   281             errCode = 
htont(errCode);
   282             data.
append( &errCode, 
sizeof(errCode) );
   305         : 
ClientCtx( clientId, clientEpStr, clientSockPtr ), url(
http::Url::urlSimple), websocket(this)
   318     bool isWebSocketWrapper = 
false;   
   323 template < 
class _ClientCtx = WsHttpClientCtx >
   330     using MessageHandlerFunction = std::function< void( ClientCtxSharedPointer clientCtxPtr, winux::AnsiString const & data, int messageType ) >;
   331     using CloseHandlerFunction = std::function< void( ClientCtxSharedPointer clientCtxPtr, winux::uint16 errCode, winux::AnsiString const & errStr ) >;
   332     using ErrorHandlerFunction = std::function< void( ClientCtxSharedPointer clientCtxPtr, WebSocketErrorCode ec ) >;
   335         : 
Server<_ClientCtx>( ip::
EndPoint( serverIp, port ), threadCount, listenBacklog, durationSec )
   356         int rc = clientCtxPtr->clientSockPtr->recvWaitUntilTarget(
   358             &clientCtxPtr->forClient.data,
   359             &clientCtxPtr->forClient.extraData,
   360             &clientCtxPtr->forClient.hadBytes,
   361             &clientCtxPtr->forClient.startpos,
   362             &clientCtxPtr->forClient.pos,
   363             this->_pool.getDurationSec(),
   365             [&clientCtxPtr] ( 
int had, 
void* ) {
   366                 clientCtxPtr->forClient.retryCount = 0; 
   370         if ( clientCtxPtr->forClient.pos != -1 ) 
   373             clientCtxPtr->requestHeaderStr = clientCtxPtr->forClient.data.toAnsi();
   374             clientCtxPtr->requestHeader.clear();
   375             clientCtxPtr->requestHeader.parse(clientCtxPtr->requestHeaderStr);
   377             clientCtxPtr->forClient.resetStatus(); 
   378             clientCtxPtr->forClient.data = std::move(clientCtxPtr->forClient.extraData); 
   380             int contentLength = 
static_cast<http::Header&
>(clientCtxPtr->requestHeader).getHeader<int>(
"Content-Length");
   381             clientCtxPtr->forClient.targetBytes = contentLength - clientCtxPtr->forClient.data.getSize(); 
   382             if ( clientCtxPtr->forClient.targetBytes > 0 )
   393         else if ( rcWait == 0 )
   395             clientCtxPtr->forClient.retryCount++;
   403                 ColorOutput( 
winux::fgRed, 
"Client[", clientCtxPtr->clientId, 
"]从客户`", clientCtxPtr->clientEpStr, 
"`接收一个请求头时长时间没有数据到来" );
   404                 ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   405                 this->removeClient(clientCtxPtr->clientId);
   411             ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   412             this->removeClient(clientCtxPtr->clientId);
   420         int rc = clientCtxPtr->clientSockPtr->recvWaitUntilSize(
   421             clientCtxPtr->forClient.targetBytes,
   422             &clientCtxPtr->forClient.data,
   423             &clientCtxPtr->forClient.hadBytes,
   424             this->_pool.getDurationSec(),
   426             [&clientCtxPtr] ( 
int had, 
void* ) {
   427                 clientCtxPtr->forClient.retryCount = 0;
   431         if ( clientCtxPtr->forClient.hadBytes == clientCtxPtr->forClient.targetBytes ) 
   434             clientCtxPtr->requestBody = std::move(clientCtxPtr->forClient.data);
   435             clientCtxPtr->forClient.resetStatus(); 
   440         else if ( rcWait == 0 )
   442             clientCtxPtr->forClient.retryCount++;
   450                 ColorOutput( 
winux::fgRed, 
"Client[", clientCtxPtr->clientId, 
"]从客户`", clientCtxPtr->clientEpStr, 
"`接收一个请求体时长时间没有数据到来" );
   451                 ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   452                 this->removeClient(clientCtxPtr->clientId);
   457             ColorOutput( 
winux::fgRed, 
"Client[", clientCtxPtr->clientId, 
"]从客户`", clientCtxPtr->clientEpStr, 
"`接收请求体出错" );
   458             ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   459             this->removeClient(clientCtxPtr->clientId);
   466         ColorOutput( 
winux::fgGreen, 
"Client[", clientCtxPtr->clientId, 
"]从客户`", clientCtxPtr->clientEpStr, 
"`接收请求头(bytes:", clientCtxPtr->requestHeaderStr.size(), 
")" );
   467         std::cout << clientCtxPtr->requestHeaderStr;
   468         ColorOutput( 
winux::fgAtrovirens, 
"Client[", clientCtxPtr->clientId, 
"]从客户`", clientCtxPtr->clientEpStr, 
"`接收请求体(bytes:", clientCtxPtr->requestBody.getSize(), 
")\n" );
   471         std::stringbuf rspBuf;
   472         std::ostream rspOut(&rspBuf);
   475         rspHdr[
"Content-Type"] = 
"text/html";
   477         clientCtxPtr->url.
clear();
   478         clientCtxPtr->url.parse( clientCtxPtr->requestHeader.getUrl() );
   481         this->_webProcess( clientCtxPtr, clientCtxPtr->requestHeader, clientCtxPtr->url, rspHdr, rspOut );
   485         if ( rspStr.size() > 0 )
   486             rspHdr(
"Content-Length") << rspStr.size();
   489         if ( clientCtxPtr->clientSockPtr->sendUntil( rspHdr.
toString() + rspStr ) )
   492             if ( 
winux::StrLower( clientCtxPtr->requestHeader[
"Connection"] ) == 
"keep-alive" )
   497             else if ( clientCtxPtr->isWebSocketWrapper ) 
   502                 this->onOpen(clientCtxPtr);
   510                 ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   511                 this->removeClient(clientCtxPtr->clientId);
   516             if ( clientCtxPtr->isWebSocketWrapper )
   522             ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   523             this->removeClient(clientCtxPtr->clientId);
   539             rspHdr[
"Upgrade"] = 
"websocket";
   540             rspHdr[
"Connection"] = 
"Upgrade";
   542             rspHdr[
"Sec-WebSocket-Accept"] = secWebsocketAccept;
   544             ColorOutput( 
winux::fgAqua, 
"Client[", clientCtxPtr->clientId, 
"]客户`", clientCtxPtr->clientEpStr, 
"`升级为websocket连接" );
   551             clientCtxPtr->isWebSocketWrapper = 
true;
   559                 rspOut << 
"This is a websocket server!";
   573         if ( !clientCtxPtr->clientSockPtr->recvUntilSize( 
sizeof(
ws::FrameBase), &frameBuf ) )
   578             goto RecvFrameFailure;
   597                 ColorOutput( 
winux::fgRed, 
"Client[", clientCtxPtr->clientId, 
"]客户`", clientCtxPtr->clientEpStr, 
"`读取16位帧载荷长度失败" );
   598                 goto RecvFrameFailure;
   610                 ColorOutput( 
winux::fgRed, 
"Client[", clientCtxPtr->clientId, 
"]客户`", clientCtxPtr->clientEpStr, 
"`读取64位帧载荷长度失败" );
   611                 goto RecvFrameFailure;
   622             if ( !clientCtxPtr->clientSockPtr->recvUntilSize( 4, &frameBuf ) )
   627                 goto RecvFrameFailure;
   632         if ( !clientCtxPtr->clientSockPtr->recvUntilSize( (
int)wantBytes, &frameBuf ) )
   636             ColorOutput( 
winux::fgRed, 
"Client[", clientCtxPtr->clientId, 
"]客户`", clientCtxPtr->clientEpStr, 
"`读取载荷数据失败" );
   637             goto RecvFrameFailure;
   647                 char * data = frame->
data<
char>();
   648                 size_t len = frame->payloadLen;
   658                 char * data = frame->
data<
char>();
   659                 int len = frame->payloadLen;
   662                 for ( 
int i = 0; i < len; ++i )
   663                     data[i] ^= frame->maskingKey[ i % 4 ];
   673                 char * data = frame->
data<
char>();
   674                 int len = 
ntoht(frame->extendedPayloadLen);
   684                 char * data = frame->
data<
char>();
   685                 int len = 
ntoht(frame->extendedPayloadLen);
   688                 for ( 
int i = 0; i < len; ++i )
   689                     data[i] ^= frame->maskingKey[ i % 4 ];
   699                 char * data = frame->
data<
char>();
   710                 char * data = frame->
data<
char>();
   715                     data[i] ^= frame->maskingKey[ i % 4 ];
   726         ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   727         this->removeClient(clientCtxPtr->clientId);
   733         ColorOutput( 
winux::fgGreen, 
"Client[", clientCtxPtr->clientId, 
"]客户`", clientCtxPtr->clientEpStr, 
"`收到一个帧{fin:", (
winux::uint)fin, 
",opcode:", opcode, 
",datasize:", payloadData.
getSize(), 
"}" );
   741                     clientCtxPtr->websocket.messageBuf.append( payloadData.
getBuf<
char>(), payloadData.
getSize() );
   742                     this->onMessage( clientCtxPtr, clientCtxPtr->websocket.messageBuf, clientCtxPtr->websocket.messageType );
   743                     clientCtxPtr->websocket.messageBuf.clear();
   744                     clientCtxPtr->websocket.messageType = 0;
   748                     clientCtxPtr->websocket.messageBuf.append( payloadData.
getBuf<
char>(), payloadData.
getSize() );
   765                     clientCtxPtr->websocket.messageBuf.append( payloadData.
getBuf<
char>(), payloadData.
getSize() );
   766                     clientCtxPtr->websocket.messageType = 
opcode;
   767                     this->onMessage( clientCtxPtr, clientCtxPtr->websocket.messageBuf, clientCtxPtr->websocket.messageType );
   768                     clientCtxPtr->websocket.messageBuf.clear();
   769                     clientCtxPtr->websocket.messageType = 0;
   773                     clientCtxPtr->websocket.messageBuf.append( payloadData.
getBuf<
char>(), payloadData.
getSize() );
   774                     clientCtxPtr->websocket.messageType = 
opcode;
   787                 if ( payloadData.
getSize() > 0 )
   790                     errCode = 
ntoht(closeData->code);
   792                     ColorOutput( 
winux::fgMaroon, 
"Client[", clientCtxPtr->clientId, 
"]客户`", clientCtxPtr->clientEpStr, 
"`收到一个Close帧{errcode:", errCode, 
",errstr:", errStr, 
"}" );
   802                     clientCtxPtr->clientSockPtr->close();
   805                     this->onClose( clientCtxPtr, errCode, errStr ); 
   808                     ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   809                     this->removeClient(clientCtxPtr->clientId);
   815                     if ( clientCtxPtr->websocket.close( errCode, errStr ) )
   818                         clientCtxPtr->clientSockPtr->close();
   821                         this->onClose( clientCtxPtr, errCode, errStr ); 
   823                         ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   824                         this->removeClient(clientCtxPtr->clientId);
   848             ColorOutput( 
winux::fgRed, 
"Client[", clientCtxPtr->clientId, 
"]客户`", clientCtxPtr->clientEpStr, 
"`收到一个意外帧{fin:",(
winux::uint)fin,
",opcode:",opcode,
",datasize:",payloadData.
getSize(),
"}" );
   849             ColorOutput( 
winux::fgFuchsia, 
"Client[", clientCtxPtr->clientId, 
"]移除客户`", clientCtxPtr->clientEpStr, 
"`,还剩", this->_clients.size() - 1, 
"客户" );
   850             this->removeClient(clientCtxPtr->clientId);
   857         if ( _openHandler ) _openHandler(clientCtxPtr);
   862         if ( _messageHandler ) _messageHandler( clientCtxPtr, data, messageType );
   867         if ( _closeHandler ) _closeHandler( clientCtxPtr, errCode, errStr );
   872         if ( _errorHandler ) _errorHandler( clientCtxPtr, ec );
 
#define EIENNET_FUNC_DECL(ret)
 
void _doRequestTask(ClientCtxSharedPointer clientCtxPtr)
 
void * getBuf() const 
暴露缓冲区指针 
 
String StrLower(String const &str)
 
bool SendWebSocketFrame(eiennet::Socket *sock, OpCode opcode, bool fin, bool mask, winux::byte *payloadData=nullptr, winux::uint payloadDataSize=0)
 
virtual void onMessage(ClientCtxSharedPointer clientCtxPtr, winux::AnsiString const &data, int messageType)
 
std::basic_string< char > AnsiString
 
MessageHandlerFunction _messageHandler
 
virtual void onStartup(ClientCtxSharedPointer clientCtxPtr) override
 
virtual void onError(ClientCtxSharedPointer clientCtxPtr, WebSocketErrorCode ec)
 
static void ColorOutput(winux::ConsoleAttr const &ca, _ArgType &&...arg)
 
void onCloseHandler(CloseHandlerFunction handler)
 
WsHttpServer(winux::String const &serverIp, winux::ushort port, int threadCount=10, int listenBacklog=10, double durationSec=0.1)
 
void _doRecvRequestHeaderTask(ClientCtxSharedPointer clientCtxPtr)
 
std::function< void(ClientCtxSharedPointer clientCtxPtr, winux::AnsiString const &data, int messageType) > MessageHandlerFunction
 
void _doRecvRequestBodyTask(ClientCtxSharedPointer clientCtxPtr)
 
OpenHandlerFunction _openHandler
 
winux::uint16 extendedPayloadLen
 
Buffer Sha1(void const *buf, size_t size)
将数据进行sha1编码,返回二进制数据 
 
std::function< void(ClientCtxSharedPointer clientCtxPtr, WebSocketErrorCode ec) > ErrorHandlerFunction
 
void onOpenHandler(OpenHandlerFunction handler)
 
std::function< void(ClientCtxSharedPointer clientCtxPtr, winux::uint16 errCode, winux::AnsiString const &errStr) > CloseHandlerFunction
 
winux::String const & getRawQueryStr() const 
获取未解析的查询段字符串.不以'?'开头. 
 
WsHttpClientCtx(winux::uint64 clientId, winux::String clientEpStr, winux::SharedPointer< ip::tcp::Socket > clientSockPtr)
 
virtual void onOpen(ClientCtxSharedPointer clientCtxPtr)
 
std::function< void(ClientCtxSharedPointer clientCtxPtr) > OpenHandlerFunction
 
void _webProcess(ClientCtxSharedPointer &clientCtxPtr, http::Header const &reqHdr, http::Url const &url, http::Header &rspHdr, std::ostream &rspOut)
 
winux::AnsiString requestHeaderStr
 
winux::AnsiString messageBuf
 
bool SendWebSocketBuffer(eiennet::Socket *sock, OpCode opcode, bool mask, winux::Buffer payloadData=winux::Buffer(), int perFrameMaxPayloadSize=-1)
 
void onMessageHandler(MessageHandlerFunction handler)
 
winux::uint64 extendedPayloadLen
 
WebSocketWrapper websocket
 
uint getSize() const 
获取数据大小 
 
缓冲区,表示内存中一块2进制数据(利用malloc/realloc进行内存分配) 
 
ErrorHandlerFunction _errorHandler
 
winux::uint64 extendedPayloadLen
 
virtual ~WsHttpClientCtx()
 
String Base64Encode(void const *buf, int size)
Base64编码 
 
winux::GrowBuffer requestBody
 
DataRecvSendCtx forClient
 
void _doRecvWebSocketFrameTask(ClientCtxSharedPointer clientCtxPtr)
 
typename Server< _ClientCtx >::ClientCtxSharedPointer ClientCtxSharedPointer
 
WebSocketErrorCode
WebSocket错误码 
 
winux::String getPath() const 
获取路径. 
 
virtual void onClose(ClientCtxSharedPointer clientCtxPtr, winux::uint16 errCode, winux::AnsiString const &errStr)
 
CloseHandlerFunction _closeHandler
 
unsigned long long uint64
 
bool close(winux::uint16 errCode=-1, winux::AnsiString const &errStr="")
 
WebSocketWrapper(ClientCtx *clientCtx)
 
winux::SharedPointer< ip::tcp::Socket > clientSockPtr
 
void onErrorHandler(ErrorHandlerFunction handler)
 
bool send(winux::AnsiString const &data, ws::OpCode opcode=ws::dataText)
 
std::basic_string< tchar > String
 
void append(void const *data, uint size)
添加数据 
 
bool SendWebSocketAnsi(eiennet::Socket *sock, OpCode opcode, bool mask, winux::AnsiString payloadData=winux::AnsiString(), int perFrameMaxPayloadSize=-1)
 
winux::uint16 extendedPayloadLen
 
void _doProcessWebSocketFrameTask(ClientCtxSharedPointer clientCtxPtr, bool fin, winux::uint opcode, winux::Buffer &payloadData)
 
http::Header requestHeader