Updated network initializing detection (#457)
* Updated network initializing detection * Feedback * Feedback * Improvements * Build break
This commit is contained in:
Родитель
e044384f62
Коммит
f819ce02db
|
@ -433,12 +433,12 @@ typedef struct _LIST_ENTRY {
|
|||
#define FACILITY_XBOX 2339
|
||||
#define MAKE_E_HC(code) MAKE_HRESULT(1, FACILITY_XBOX, code)
|
||||
|
||||
#define E_HC_NOT_INITIALISED MAKE_E_HC(0x5001)
|
||||
#define E_HC_PERFORM_ALREADY_CALLED MAKE_E_HC(0x5003)
|
||||
#define E_HC_ALREADY_INITIALISED MAKE_E_HC(0x5004)
|
||||
#define E_HC_CONNECT_ALREADY_CALLED MAKE_E_HC(0x5005)
|
||||
#define E_HC_NO_NETWORK MAKE_E_HC(0x5006)
|
||||
#define E_HC_NETWORK_NOT_READY MAKE_E_HC(0x5007)
|
||||
#define E_HC_NOT_INITIALISED MAKE_E_HC(0x5001) // 0x89235001
|
||||
#define E_HC_PERFORM_ALREADY_CALLED MAKE_E_HC(0x5003) // 0x89235003
|
||||
#define E_HC_ALREADY_INITIALISED MAKE_E_HC(0x5004) // 0x89235004
|
||||
#define E_HC_CONNECT_ALREADY_CALLED MAKE_E_HC(0x5005) // 0x89235005
|
||||
#define E_HC_NO_NETWORK MAKE_E_HC(0x5006) // 0x89235006
|
||||
#define E_HC_NETWORK_NOT_INITIALIZED MAKE_E_HC(0x5007) // 0x89235007
|
||||
|
||||
typedef uint32_t HCMemoryType;
|
||||
typedef struct HC_WEBSOCKET* HCWebsocketHandle;
|
||||
|
|
|
@ -72,6 +72,11 @@ typedef struct http_singleton
|
|||
uint32_t m_timeoutWindowInSeconds = DEFAULT_TIMEOUT_WINDOW_IN_SECONDS;
|
||||
uint32_t m_retryDelayInSeconds = DEFAULT_RETRY_DELAY_IN_SECONDS;
|
||||
|
||||
#if HC_PLATFORM == HC_PLATFORM_GSDK
|
||||
bool m_networkInitialized{ true };
|
||||
HMODULE m_networkModule{ nullptr };
|
||||
#endif
|
||||
|
||||
#if !HC_NOWEBSOCKETS
|
||||
WebSocketPerformInfo const m_websocketPerform;
|
||||
#endif
|
||||
|
|
|
@ -1038,6 +1038,22 @@ NAMESPACE_XBOX_HTTP_CLIENT_END
|
|||
|
||||
#if HC_PLATFORM == HC_PLATFORM_GSDK
|
||||
typedef DWORD(WINAPI *GetNetworkConnectivityHintProc)(NL_NETWORK_CONNECTIVITY_HINT*);
|
||||
typedef DWORD(WINAPI *NotifyNetworkConnectivityHintChangeProc)(PNETWORK_CONNECTIVITY_HINT_CHANGE_CALLBACK, PVOID, BOOLEAN, PHANDLE);
|
||||
|
||||
static void NetworkConnectivityHintChangedCallback(
|
||||
_In_ void* context,
|
||||
_In_ NL_NETWORK_CONNECTIVITY_HINT connectivityHint
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(context);
|
||||
|
||||
auto singleton = get_http_singleton(false);
|
||||
|
||||
if (singleton != nullptr)
|
||||
{
|
||||
singleton->m_networkInitialized = connectivityHint.ConnectivityLevel != NetworkConnectivityLevelHintUnknown;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT Internal_InitializeHttpPlatform(HCInitArgs* args, PerformEnv& performEnv) noexcept
|
||||
|
@ -1045,36 +1061,6 @@ HRESULT Internal_InitializeHttpPlatform(HCInitArgs* args, PerformEnv& performEnv
|
|||
assert(args == nullptr);
|
||||
UNREFERENCED_PARAMETER(args);
|
||||
|
||||
#if HC_PLATFORM == HC_PLATFORM_GSDK
|
||||
if (XGameRuntimeIsFeatureAvailable(XGameRuntimeFeature::XNetworking))
|
||||
{
|
||||
HMODULE hModule = LoadLibrary(TEXT("iphlpapi.dll"));
|
||||
|
||||
if (hModule != nullptr)
|
||||
{
|
||||
GetNetworkConnectivityHintProc getNetworkConnectivityHint =
|
||||
(GetNetworkConnectivityHintProc)GetProcAddress(hModule, "GetNetworkConnectivityHint");
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
bool networkNotReady = false;
|
||||
|
||||
if (getNetworkConnectivityHint != nullptr)
|
||||
{
|
||||
NL_NETWORK_CONNECTIVITY_HINT connectivityHint{};
|
||||
hr = HRESULT_FROM_WIN32(getNetworkConnectivityHint(&connectivityHint));
|
||||
networkNotReady = connectivityHint.ConnectivityLevel == NetworkConnectivityLevelHintUnknown;
|
||||
}
|
||||
|
||||
FreeLibrary(hModule);
|
||||
|
||||
if (SUCCEEDED(hr) && networkNotReady)
|
||||
{
|
||||
return E_HC_NETWORK_NOT_READY;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
performEnv.reset(new (std::nothrow) HC_PERFORM_ENV());
|
||||
if (!performEnv) { return E_OUTOFMEMORY; }
|
||||
|
||||
|
@ -1083,6 +1069,15 @@ HRESULT Internal_InitializeHttpPlatform(HCInitArgs* args, PerformEnv& performEnv
|
|||
|
||||
void Internal_CleanupHttpPlatform(HC_PERFORM_ENV* performEnv) noexcept
|
||||
{
|
||||
#if HC_PLATFORM == HC_PLATFORM_GSDK
|
||||
auto singleton = get_http_singleton(false);
|
||||
if (singleton != nullptr && singleton->m_networkModule != nullptr)
|
||||
{
|
||||
FreeLibrary(singleton->m_networkModule);
|
||||
singleton->m_networkModule = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete performEnv;
|
||||
}
|
||||
|
||||
|
@ -1154,6 +1149,51 @@ void CALLBACK Internal_HCHttpCallPerformAsync(
|
|||
assert(env != nullptr);
|
||||
UNREFERENCED_PARAMETER(context);
|
||||
|
||||
|
||||
#if HC_PLATFORM == HC_PLATFORM_GSDK
|
||||
if (XGameRuntimeIsFeatureAvailable(XGameRuntimeFeature::XNetworking))
|
||||
{
|
||||
auto singleton = get_http_singleton(true);
|
||||
if (singleton != nullptr)
|
||||
{
|
||||
if (singleton->m_networkModule == nullptr)
|
||||
{
|
||||
singleton->m_networkModule = LoadLibrary(TEXT("iphlpapi.dll"));
|
||||
|
||||
if (singleton->m_networkModule != nullptr)
|
||||
{
|
||||
GetNetworkConnectivityHintProc getNetworkConnectivityHint =
|
||||
(GetNetworkConnectivityHintProc)GetProcAddress(singleton->m_networkModule, "GetNetworkConnectivityHint");
|
||||
|
||||
NotifyNetworkConnectivityHintChangeProc notifyNetworkConnectivityHintChange =
|
||||
(NotifyNetworkConnectivityHintChangeProc)GetProcAddress(singleton->m_networkModule, "NotifyNetworkConnectivityHintChange");
|
||||
|
||||
if (getNetworkConnectivityHint != nullptr && notifyNetworkConnectivityHintChange != nullptr)
|
||||
{
|
||||
NL_NETWORK_CONNECTIVITY_HINT connectivityHint{};
|
||||
HRESULT hr = HRESULT_FROM_WIN32(getNetworkConnectivityHint(&connectivityHint));
|
||||
singleton->m_networkInitialized = SUCCEEDED(hr) && connectivityHint.ConnectivityLevel != NetworkConnectivityLevelHintUnknown;
|
||||
|
||||
HANDLE networkConnectivityChangedHandle;
|
||||
std::weak_ptr<http_singleton> singletonWeakPtr = singleton;
|
||||
(void)HRESULT_FROM_WIN32(notifyNetworkConnectivityHintChange(
|
||||
NetworkConnectivityHintChangedCallback,
|
||||
nullptr,
|
||||
TRUE,
|
||||
&networkConnectivityChangedHandle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!singleton->m_networkInitialized)
|
||||
{
|
||||
XAsyncComplete(asyncBlock, E_HC_NETWORK_NOT_INITIALIZED, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isWebsocket = false;
|
||||
std::shared_ptr<xbox::httpclient::winhttp_http_task> httpTask = http_allocate_shared<winhttp_http_task>(
|
||||
asyncBlock, call, env->m_hSession, env->m_proxyType, isWebsocket);
|
||||
|
|
|
@ -390,6 +390,8 @@ void retry_http_call_until_done(
|
|||
return;
|
||||
}
|
||||
|
||||
auto callStatus = XAsyncGetStatus(nestedAsyncBlock, false);
|
||||
|
||||
retry_context* retryContext = static_cast<retry_context*>(nestedAsyncBlock->context);
|
||||
auto responseReceivedTime = chrono_clock_t::now();
|
||||
|
||||
|
@ -402,7 +404,7 @@ void retry_http_call_until_done(
|
|||
}
|
||||
delete nestedAsyncBlock;
|
||||
|
||||
if (http_call_should_retry(retryContext->call, responseReceivedTime))
|
||||
if (SUCCEEDED(callStatus) && http_call_should_retry(retryContext->call, responseReceivedTime))
|
||||
{
|
||||
if (retryContext->call->traceCall) { HC_TRACE_INFORMATION(HTTPCLIENT, "HCHttpCallPerformExecute [ID %llu] Retry after %lld ms", retryContext->call->id, retryContext->call->delayBeforeRetry.count()); }
|
||||
std::lock_guard<std::recursive_mutex> lock(httpSingleton->m_callRoutedHandlersLock);
|
||||
|
@ -416,7 +418,7 @@ void retry_http_call_until_done(
|
|||
}
|
||||
else
|
||||
{
|
||||
XAsyncComplete(retryContext->outerAsyncBlock, S_OK, 0);
|
||||
XAsyncComplete(retryContext->outerAsyncBlock, callStatus, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче