Verbinden von Geräten über RemotesitzungenConnect devices through remote sessions

Mit dem Feature "Remote Sitzungen" kann eine APP über eine Sitzung eine Verbindung mit anderen Geräten herstellen, entweder für explizites App-Messaging oder für den Broker Austausch von System verwalteten Daten, wie z. b. spatialentitystore für die holografische Freigabe zwischen Windows Holographic-Geräten.The Remote Sessions feature allows an app to connect to other devices through a session, either for explicit app messaging or for brokered exchange of system-managed data, such as the SpatialEntityStore for holographic sharing between Windows Holographic devices.

Remote Sitzungen können von jedem beliebigen Windows-Gerät erstellt werden, und ein beliebiges Windows-Gerät kann einen Join anfordern (obwohl Sitzungen nur über eine nur-Einladung-Sichtbarkeit verfügen können), einschließlich der von anderen Benutzern angemeldeten Geräte.Remote sessions can be created by any Windows device, and any Windows device can request to join (although sessions can have invite-only visibility), including devices signed in by other users. Dieser Leitfaden enthält grundlegende Beispielcodes für alle wichtigen Szenarien, in denen Remote Sitzungen verwendet werden.This guide provides basic sample code for all of the major scenarios that make use of remote sessions. Dieser Code kann in ein vorhandenes App-Projekt integriert und nach Bedarf geändert werden.This code can be incorporated into an existing app project and modified as necessary. Eine End-to-End-Implementierung finden Sie in der Beispiel-App für Quiz Spiele).For an end-to-end implementation, see the Quiz Game sample app).

Vorläufige EinrichtungPreliminary setup

Hinzufügen der Funktionen „remoteSystem“Add the remoteSystem capability

Damit Ihre App eine App auf einem Remotegerät starten kann, müssen Sie Ihrem App-Paketmanifest die Funktion remoteSystem hinzufügen.In order for your app to launch an app on a remote device, you must add the remoteSystem capability to your app package manifest. Sie können den Paket Manifest-Designer verwenden, um ihn hinzuzufügen, indem Sie auf der Registerkarte " Funktionen " Remote System auswählen, oder Sie können die folgende Zeile manuell der Datei " Package. appxmanifest " des Projekts hinzufügen.You can use the package manifest designer to add it by selecting Remote System on the Capabilities tab, or you can manually add the following line to your project's Package.appxmanifest file.

<Capabilities>
   <uap3:Capability Name="remoteSystem"/>
</Capabilities>

Benutzer übergreifende Ermittlung auf dem Gerät aktivierenEnable cross-user discovering on the device

Remote Sitzungen sind darauf ausgerichtet, mehrere verschiedene Benutzer zu verbinden, sodass für die beteiligten Geräte die Benutzer übergreifende Freigabe aktiviert werden muss.Remote Sessions is geared toward connecting multiple different users, so the devices involved will need to have Cross-User Sharing enabled. Dies ist eine Systemeinstellung, die mit einer statischen Methode in der Remotesystem -Klasse abgefragt werden kann:This is a system setting that can be queried with a static method in the RemoteSystem class:

if (!RemoteSystem.IsAuthorizationKindEnabled(RemoteSystemAuthorizationKind.Anonymous)) {
    // The system is not authorized to connect to cross-user devices. 
    // Inform the user that they can discover more devices if they
    // update the setting to "Everyone nearby".
}

Um diese Einstellung zu ändern, muss der Benutzer die app " Einstellungen " öffnen.To change this setting, the user must open the Settings app. Im Menü für die gemeinsame Nutzung von SystemFreigaben > Shared experiences > über Geräte gibt es eine Dropdown Liste, in der der Benutzer angeben kann, mit welchen Geräten das System gemeinsam genutzt werden kann.In the System > Shared experiences > Share across devices menu, there is a drop-down box where the user can specify which devices their system can share with.

Seite mit Einstellungen für freigegebene Erfahrungen

Erforderliche Namespaces einbeziehenInclude the necessary namespaces

Um alle Code Ausschnitte in dieser Anleitung verwenden zu können, benötigen Sie die folgenden using Anweisungen in der Klassendatei (en).In order to use all of the code snippets in this guide, you will need the following using statements in your class file(s).

using System.Runtime.Serialization.Json;
using Windows.Foundation.Collections;
using Windows.System.RemoteSystems;

Erstellen einer Remote SitzungCreate a remote session

Um eine Remote Sitzungs Instanz zu erstellen, müssen Sie mit einem remotesystemsessioncontroller -Objekt beginnen.To create a remote session instance, you must start with a RemoteSystemSessionController object. Verwenden Sie das folgende Framework, um eine neue Sitzung zu erstellen und Joinanforderungen von anderen Geräten zu behandeln.Use the following framework to create a new session and handle join requests from other devices.

public async void CreateSession() {
    
    // create a session controller
    RemoteSystemSessionController manager = new RemoteSystemSessionController("Bob’s Minecraft game");
    
    // register the following code to handle the JoinRequested event
    manager.JoinRequested += async (sender, args) => {
        // Get the deferral
        var deferral = args.GetDeferral();
        
        // display the participant (args.JoinRequest.Participant) on UI, giving the 
        // user an opportunity to respond
        // ...
        
        // If the user chooses "accept", accept this remote system as a participant
        args.JoinRequest.Accept();
    };
    
    // create and start the session
    RemoteSystemSessionCreationResult createResult = await manager.CreateSessionAsync();
    
    // handle the creation result
    if (createResult.Status == RemoteSystemSessionCreationStatus.Success) {
        // creation was successful, get a reference to the session
        RemoteSystemSession currentSession = createResult.Session;
        
        // optionally subscribe to the disconnection event
        currentSession.Disconnected += async (sender, args) => {
            // update the UI, using args.Reason
            //...
        };
    
        // Use session (see later section)
        //...
    
    } else if (createResult.Status == RemoteSystemSessionCreationStatus.SessionLimitsExceeded) {
        // creation failed. Optionally update UI to indicate that there are too many sessions in progress
    } else {
        // creation failed for an unknown reason. Optionally update UI
    }
}

Nur Einladung für eine Remote Sitzung erstellenMake a remote session invite-only

Wenn Sie verhindern möchten, dass Ihre Remote Sitzung öffentlich erkennbar ist, können Sie Sie nur einladen.If you wish to keep your remote session from being publicly discoverable, you can make it invite-only. Nur die Geräte, die eine Einladung empfangen, können Joinanforderungen senden.Only the devices that receive an invitation will be able to send join requests.

Die Prozedur ist größtenteils mit der oben genannten identisch, aber wenn Sie die remotesystemsessioncontroller -Instanz erstellen, übergeben Sie ein konfiguriertes remotesystemsessionoptions -Objekt.The procedure is mostly the same as above, but when constructing the RemoteSystemSessionController instance, you will pass in a configured RemoteSystemSessionOptions object.

// define the session options with the invite-only designation
RemoteSystemSessionOptions sessionOptions = new RemoteSystemSessionOptions();
sessionOptions.IsInviteOnly = true;

// create the session controller
RemoteSystemSessionController manager = new RemoteSystemSessionController("Bob's Minecraft game", sessionOptions);

//...

Zum Senden einer Einladung benötigen Sie einen Verweis auf das empfangende Remote System (über die normale Remote System Ermittlung abgerufen).To send an invitation, you must have a reference to the receiving remote system (acquired through normal remote system discovery). Übergeben Sie diesen Verweis einfach an die sendinvitationasync -Methode des Sitzungs Objekts.Simply pass this reference into the session object's SendInvitationAsync method. Alle Teilnehmer in einer Sitzung verfügen über einen Verweis auf die Remote Sitzung (siehe nächster Abschnitt), sodass jeder Teilnehmer eine Einladung senden kann.All of the participants in a session have a reference to the remote session (see next section), so any participant can send an invitation.

// "currentSession" is a reference to a RemoteSystemSession.
// "guestSystem" is a previously discovered RemoteSystem instance
currentSession.SendInvitationAsync(guestSystem); 

Entdecken und beitreten zu einer Remote SitzungDiscover and join a remote session

Der Prozess der Ermittlung von Remote Sitzungen wird von der remotesystemsessionwatcher -Klasse behandelt und ähnelt der Ermittlung einzelner Remote Systeme.The process of discovering remote sessions is handled by the RemoteSystemSessionWatcher class and is similar to discovering individual remote systems.

public void DiscoverSessions() {
    
    // create a watcher for remote system sessions
    RemoteSystemSessionWatcher sessionWatcher = RemoteSystemSession.CreateWatcher();
    
    // register a handler for the "added" event
    sessionWatcher.Added += async (sender, args) => {
        
        // get a reference to the info about the discovered session
        RemoteSystemSessionInfo sessionInfo = args.SessionInfo;
        
        // Optionally update the UI with the sessionInfo.DisplayName and 
        // sessionInfo.ControllerDisplayName strings. 
        // Save a reference to this RemoteSystemSessionInfo to use when the
        // user selects this session from the UI
        //...
    };
    
    // Begin watching
    sessionWatcher.Start();
}

Wenn eine remotesystemsessioninfo -Instanz abgerufen wird, kann Sie verwendet werden, um eine joinanforderung an das Gerät auszugeben, das die entsprechende Sitzung steuert.When a RemoteSystemSessionInfo instance is obtained, it can be used to issue a join request to the device that controls the corresponding session. Eine akzeptierte joinanforderung gibt asynchron ein remotesystemsessionjoinresult -Objekt zurück, das einen Verweis auf die verknüpfte Sitzung enthält.An accepted join request will asynchronously return a RemoteSystemSessionJoinResult object that contains a reference to the joined session.

public async void JoinSession(RemoteSystemSessionInfo sessionInfo) {

    // issue a join request and wait for result.
    RemoteSystemSessionJoinResult joinResult = await sessionInfo.JoinAsync();
    if (joinResult.Status == RemoteSystemSessionJoinStatus.Success) {
        // Join request was approved

        // RemoteSystemSession instance "currentSession" was declared at class level.
        // Assign the value obtained from the join result.
        currentSession = joinResult.Session;
        
        // note connection and register to handle disconnection event
        bool isConnected = true;
        currentSession.Disconnected += async (sender, args) => {
            isConnected = false;

            // update the UI with args.Reason value
        };
        
        if (isConnected) {
            // optionally use the session here (see next section)
            //...
        }
    } else {
        // Join was unsuccessful.
        // Update the UI, using joinResult.Status value to show cause of failure.
    }
}

Ein Gerät kann gleichzeitig mit mehreren Sitzungen verknüpft werden.A device can be joined to multiple sessions at the same time. Aus diesem Grund kann es wünschenswert sein, die Verbindungsfunktionen von der eigentlichen Interaktion mit den einzelnen Sitzungen zu trennen.For this reason, it may be desirable to separate the joining functionality from the actual interaction with each session. Solange ein Verweis auf die remotesystemsession -Instanz in der APP verwaltet wird, kann die Kommunikation über diese Sitzung versucht werden.As long as a reference to the RemoteSystemSession instance is maintained in the app, communication can be attempted over that session.

Freigeben von Nachrichten und Daten über eine Remote SitzungShare messages and data through a remote session

Empfangen von NachrichtenReceive messages

Sie können Nachrichten und Daten mit anderen Teilnehmer Geräten in der Sitzung austauschen, indem Sie eine remotesystemsessionmessagechannel -Instanz verwenden, die einen einzelnen Sitzungs weiten Kommunikationskanal darstellt.You can exchange messages and data with other participant devices in the session by using a RemoteSystemSessionMessageChannel instance, which represents a single session-wide communication channel. Sobald Sie initialisiert ist, beginnt Sie mit dem lauschen auf eingehende Nachrichten.As soon as it's initialized, it begins listening for incoming messages.

Hinweis

Nachrichten müssen nach dem Senden und empfangen serialisiert und aus Byte Arrays deserialisiert werden.Messages must be serialized and deserialized from byte arrays upon sending and receiving. Diese Funktion ist in den folgenden Beispielen enthalten, kann aber separat implementiert werden, um eine bessere Code Modularität zu erzielen.This functionality is included in the following examples, but it can be implemented separately for better code modularity. Ein Beispiel hierfür finden Sie in der Beispiel- App).See the sample app) for an example of this.

public async void StartReceivingMessages() {
    
    // Initialize. The channel name must be known by all participant devices 
    // that will communicate over it.
    RemoteSystemSessionMessageChannel messageChannel = new RemoteSystemSessionMessageChannel(currentSession, 
        "Everyone in Bob's Minecraft game", 
        RemoteSystemSessionMessageChannelReliability.Reliable);
    
    // write the handler for incoming messages on this channel
    messageChannel.ValueSetReceived += async (sender, args) => {
        
        // Update UI: a message was received from the participant args.Sender
        
        // Deserialize the message 
        // (this app must know what key to use and what object type the value is expected to be)
        ValueSet receivedMessage = args.Message;
        object rawData = receivedMessage["appKey"]);
        object value = new ExpectedType(); // this must be whatever type is expected

        using (var stream = new MemoryStream((byte[])rawData)) {
            value = new DataContractJsonSerializer(value.GetType()).ReadObject(stream);
        }
        
        // do something with the "value" object
        //...
    };
}

Senden von NachrichtenSend messages

Wenn der Kanal eingerichtet wird, ist das Senden einer Nachricht an alle Sitzungsteilnehmer unkompliziert.When the channel is established, sending a message to all of the session participants is straightforward.

public async void SendMessageToAllParticipantsAsync(RemoteSystemSessionMessageChannel messageChannel, object value){

    // define a ValueSet message to send
    ValueSet message = new ValueSet();
    
    // serialize the "value" object to send
    using (var stream = new MemoryStream()){
        new DataContractJsonSerializer(value.GetType()).WriteObject(stream, value);
        byte[] rawData = stream.ToArray();
            message["appKey"] = rawData;
    }
    
    // Send message to all participants. Ordering is not guaranteed.
    await messageChannel.BroadcastValueSetAsync(message);
}

Damit eine Nachricht nur an bestimmte Teilnehmer gesendet werden kann, müssen Sie zunächst einen Ermittlungsprozess initiieren, um Verweise auf die Remote Systeme zu erhalten, die an der Sitzung teilnehmen.In order to send a message to only certain participant(s), you must first initiate a discovery process to acquire references to the remote systems participating in the session. Dies ist vergleichbar mit dem Prozess der Ermittlung von Remote Systemen außerhalb einer Sitzung.This is similar to the process of discovering remote systems outside of a session. Verwenden Sie eine remotesystemsessionparticipantwatcher -Instanz, um die Teilnehmer Geräte einer Sitzung zu suchen.Use a RemoteSystemSessionParticipantWatcher instance to find a session's participant devices.

public void WatchForParticipants() {
    // "currentSession" is a reference to a RemoteSystemSession.
    RemoteSystemSessionParticipantWatcher watcher = currentSession.CreateParticipantWatcher();

    watcher.Added += (sender, participant) => {
        // save a reference to "participant"
        // optionally update UI
    };   

    watcher.Removed += (sender, participant) => {
        // remove reference to "participant"
        // optionally update UI
    };

    watcher.EnumerationCompleted += (sender, args) => {
        // Apps can delay data model render up until this point if they wish.
    };

    // Begin watching for session participants
    watcher.Start();
}

Wenn eine Liste der Verweise auf Sitzungsteilnehmer abgerufen wird, können Sie eine Nachricht an eine beliebige Gruppe von Ihnen senden.When a list of references to session participants is obtained you can send a message to any set of them.

Zum Senden einer Nachricht an einen einzelnen Teilnehmer (idealerweise vom Benutzer auf dem Bildschirm ausgewählt) übergeben Sie einfach den Verweis an eine Methode wie die folgende.To send a message to a single participant (ideally selected on-screen by the user), simply pass the reference into a method like the following.

public async void SendMessageToParticipantAsync(RemoteSystemSessionMessageChannel messageChannel, RemoteSystemSessionParticipant participant, object value) {
    
    // define a ValueSet message to send
    ValueSet message = new ValueSet();
    
    // serialize the "value" object to send
    using (var stream = new MemoryStream()){
        new DataContractJsonSerializer(value.GetType()).WriteObject(stream, value);
        byte[] rawData = stream.ToArray();
            message["appKey"] = rawData;
    }

    // Send message to the participant
    await messageChannel.SendValueSetAsync(message,participant);
}

Um eine Nachricht an mehrere Teilnehmer zu senden (idealerweise vom Benutzer auf dem Bildschirm ausgewählt), fügen Sie Sie einem Listen Objekt hinzu, und übergeben Sie die Liste an eine Methode wie die folgende.To send a message to multiple participants (ideally selected on-screen by the user), add them to a list object and pass the list into a method like the following.

public async void SendMessageToListAsync(RemoteSystemSessionMessageChannel messageChannel, IReadOnlyList<RemoteSystemSessionParticipant> myTeam, object value){

    // define a ValueSet message to send
    ValueSet message = new ValueSet();
    
    // serialize the "value" object to send
    using (var stream = new MemoryStream()){
        new DataContractJsonSerializer(value.GetType()).WriteObject(stream, value);
        byte[] rawData = stream.ToArray();
            message["appKey"] = rawData;
    }

    // Send message to specific participants. Ordering is not guaranteed.
    await messageChannel.SendValueSetToParticipantsAsync(message, myTeam);   
}