通用应用程序:在“EnableTransferOwnership”之后无法绑定`StreamSocketListener`

时间:2015-08-15 16:06:24

标签: win-universal-app windows-10 uwp

我正在关注this sample以实现后台服务器通用应用。这是实验代码:

void MainPage::OnConnectionReceived(StreamSocketListener^ sender, StreamSocketListenerConnectionReceivedEventArgs^ args)
{
     OutputDebugString(L"Connection received\n");

     // No idea how to transfer request handling from foreground to background task!
}

void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
    // Code to register background task is omitted

    auto listener = ref new StreamSocketListener();
    listener->Control->QualityOfService = SocketQualityOfService::Normal;

    try
    {
        listener->EnableTransferOwnership(Task->TaskId, SocketActivityConnectedStandbyAction::Wake);
    }
    catch (...)
    {
        OutputDebugString(L"Error: cannot transfer ownership\n");
    }

    listener->ConnectionReceived += ref new TypedEventHandler<StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^>(this, &MainPage::OnConnectionReceived);

    create_task(listener->BindServiceNameAsync("56789", SocketProtectionLevel::PlainSocket))
        .then([this]()
    {
        OutputDebugString(L"Server started on port 56789\n");

        auto m_httpClient = ref new HttpClient();
        auto request = ref new HttpRequestMessage(HttpMethod::Get, ref new Uri("http://" + ip + ":56789/"));
        auto request_operation = m_httpClient->SendRequestAsync(request, HttpCompletionOption::ResponseContentRead);

        return create_task(request_operation);
    }).then([this](task<HttpResponseMessage^> previousTask)
    {
        try {
            auto response = previousTask.get();
            // Code to process the response is omitted as it is irrelevant to the question
        }
        catch (Exception^ ex)
        {
            OutputDebugString(("Error: " + ex->Message + "\n")->Data());
        }
    });
}

在运行时,我收到错误:引用的对象类型不支持尝试的操作。表明BindServiceNameAsync失败,我不知道为什么我有在进行绑定之前,请按照文档执行EnableTransferOwnership。我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

您正在所引用的对象类型不支持尝试的操作。因为您使用的是SocketActivityConnectedStandbyAction::Wake。将其更改为SocketActivityConnectedStandbyAction::DoNotWake

以下伪代码应该让您了解要使StreamSocketListenerSocketActivityTrigger一起使用还需要做些什么:

// TODO: task = socketTaskBuilder.Register();

socketListener = new StreamSocketListener();

socketListener.ConnectionReceived += OnConnected;

await socketListener.BindServiceNameAsync(port);

socketListener.EnableTransferOwnership(
    task.TaskId,
    SocketActivityConnectedStandbyAction.DoNotWake);

// This is required, otherwise you may get error:
// A device attached to the system is not functioning.
// (Exception from HRESULT: 0x8007001F)
await socketListener.CancelIOAsync();

socketListener.TransferOwnership(socketId); 

然后,在后台任务中执行:

public async void Run(IBackgroundTaskInstance taskInstance)
{
    var deferral = taskInstance.GetDeferral();

    var details = taskInstance.TriggerDetails as
        SocketActivityTriggerDetails;

    var socketInformation = details.SocketInformation;
    var streamSocket = socketInformation.StreamSocket;
    var socketListener = socketInformation.StreamSocketListener;

    switch (details.Reason)
    {
        case SocketActivityTriggerReason.ConnectionAccepted:

            // TODO: read, write, etc.

            break;
        default:
            // ...

            break;
    }

    // ...

    deferral.Complete();
}