Your code uses the IXMLHTTPRequest2 interface to send and receive data using the HTTP protocol. You use IXMLHTTPRequest2 on Xbox One in the same way as you would use it on Windows 8, and can consult MSDN for extensive information about using the interface.
There are a few special considerations when using IXMLHTTPRequest2 (IXHR2) on Xbox One.
Note IXmlHttpRequest2 and IXmlHttpRequest2Callback are cross-OS calls. For more information, see Cross-OS Calls.
The following sample code shows how to instantiate an IXMLHTTPRequest2 instance.
#include "ixmlhttprequest2.h"
HRESULT hr = CoCreateInstance(__uuidof(FreeThreadedXMLHTTP60), NULL, CLSCTX_SERVER, IID_PPV_ARGS(&pXHR );
if (FAILED(hr))
{
wprintf(L"CoCreateInstance(XHR2) = 0x%08X", hr));
return false;
}
Note If you’re used to programming with COM on Windows, you might be used to calling CoCreateInstance with CLSCTX_INPROC_SERVER, rather than CLSCTX_SERVER, as shown. In Xbox One programs, CLSCTX_SERVER is required.
Once you have created the IXMLHTTPRequest2 instance in the manner shown, you use it like any other COM object.
IXMLHTTPRequest2 (IXHR2) on Xbox One has additional security restrictions for platform protection. These limit cipher and mode support for this API:
When you call IXMLHTTPRequest2::Send or IXMLHTTPRequest2::SetCustomResponseStream, you can pass in an object that implements the ISequentialStream interface. ISequentialStream is a COM interface, and you have to implement the object that provides the interface. Xbox One system code makes interface calls on the object you passed in. Your object must properly implement both IDispatch and ISequentialStream in order to work properly with IXMLHTTPRequest2 on Xbox One.
We strongly recommend that you use the Windows Runtime C++ Template Library (WRL) and derive your class that implements ISequentialStream from the WRL RuntimeClass class, specifying both IDispatch and ISequentialStream when you declare your class as inheriting from the RuntimeClass template. Taking advantage of the WRL templates will help ensure that you encounter no problems with marshaling your COM object across partition boundaries.
See the Web Services Sample for an example of using IXMLHTTPRequest2, and particularly the XboxSampleFramework::RequestStream class for a working implementation of the class that implements ISequentialStream and IDispatch.
This requirement is more strict than the requirements imposed when calling IXMLHTTPRequest2 in a Windows app, so it is possible for an implementation that worked in a Windows app to fail on Xbox One. This is because IXMLHTTPRequest2 calls you make in the exclusive partition are marshaled to the shared partition for execution, causing your ISequentialStream object to be marshaled across a partition boundary. In Windows apps, it would be unusual for the object to be marshaled across process boundaries, so errors in COM implementation that only surface when the object is marshalled, would not be encountered. An implementation that meets the requirements for Xbox One will also work for Windows apps. Using WRL ensures that your COM implementation marshals properly across process or partition boundaries in both Windows and Xbox One.
XHR_PROP_ONDATA_THRESHOLD is a new IXMLHTTPRequest2 property, specific to Xbox One that allows your code to control how often the HTTP stack calls IXMLHTTPRequest2Callback::OnDataAvailable during a download. By default the HTTP stack calls OnDataAvailable constantly even though your code may only be able to effectively utilize the data in larger chunks, or might only act once the download is complete. These extra callbacks slow the performance of both the HTTP request (due to unneeded remote procedure call overhead) and the added CPU usage in your title, to process the data constantly. Your code can change the default behavior by specifying a preferred minimum data size before OnDataAvailable is called. This reduces the processing burden on your title, and increases the overall HTTP download speed.
The following examples show how to use XHR_PROP_ONDATA_THRESHOLD.
This code sets XHR_PROP_ONDATA_THRESHOLD to continuously call OnDataAvailable as data comes in. This behavior is the same as the legacy behavior in versions of the XDK before this property was added. Note that this usage is not recommended.
// Specifies the HTTP stack should continuously call OnDataAvailable as data comes in with no threshold.
// For backwards compatibility this is the default behavior, but not the suggested setting.
// XHR_PROP_ONDATA_ALWAYS is 0x0, which is now defined in the ixmlhttprequest.h
_xhr->SetProperty(XHR_PROP_ONDATA_THRESHOLD, XHR_PROP_ONDATA_ALWAYS);
This code sets XHR_PROP_ONDATA_THRESHOLD to XHR_PROP_ONDATA_NEVER, ensuring that OnDataAvailable is never called during the download. Instead, OnResponseReceived will be called when the download is complete. This is the recommended property value for HTTP requests where your code will not use the downloaded data until the download is complete.
// Specifies the HTTP stack should never call OnDataAvailable, and the final download will be read during the
// IXMLHTTPRequest2Callback::OnResponseReceived call.
// This is the recommended property for HTTP requests where only the full download is utilized instead of streamed.
// Using this setting can give a performance increase of up to 5 times faster than the previous scenario.
// XHR_PROP_ONDATA_NEVER is 0xFFFFFFFFFFFFFFFF, which is now defined in the ixmlhttprequest.h
_xhr->SetProperty(XHR_PROP_ONDATA_THRESHOLD, XHR_PROP_ONDATA_NEVER);
This code sets XHR_PROP_ONDATA_THRESHOLD to call OnDataAvailable when at least 64 Kbytes are available.
// Specifies the HTTP stack should only call OnDataAvailable when at least 64k bytes are available.
// Setting the threshold to a specific value is great way to increase performance for streaming data
// and should be tweaked for the title’s streaming requirements. This value can be between the
// values 0x1 to 0xFFFFFFFFFFFFFFFE. Please note that the data available when OnDataAvailable is called
// will be slightly larger than the threshold, so the buffer used to read the data should be larger in order
// prevent the need to call ISequentialStream::Read more than once.
_xhr->SetProperty(XHR_PROP_ONDATA_THRESHOLD, 0xFFFF);
API reference