Menyambungkan perangkat melalui sesi jarak jauh

Fitur Sesi Jarak Jauh memungkinkan aplikasi terhubung ke perangkat lain melalui sesi, baik untuk olahpesan aplikasi eksplisit atau untuk pertukaran broker data yang dikelola sistem, seperti SpatialEntityStore untuk berbagi holografik antara perangkat Holografik Windows.

Sesi jarak jauh dapat dibuat oleh perangkat Windows apa pun, dan perangkat Windows apa pun dapat meminta untuk bergabung (meskipun sesi dapat memiliki visibilitas khusus undangan), termasuk perangkat yang masuk oleh pengguna lain. Panduan ini menyediakan kode sampel dasar untuk semua skenario utama yang memanfaatkan sesi jarak jauh. Kode ini dapat dimasukkan ke dalam proyek aplikasi yang ada dan dimodifikasi seperlunya. Untuk implementasi end-to-end, lihat aplikasi sampel Quiz Game).

Penyiapan awal

Menambahkan kemampuan remoteSystem

Agar aplikasi Anda dapat meluncurkan aplikasi di perangkat jarak jauh, Anda harus menambahkan kemampuan ke remoteSystem manifes paket aplikasi Anda. Anda dapat menggunakan perancang manifes paket untuk menambahkannya dengan memilih Sistem Jarak Jauh pada tab Kemampuan , atau Anda dapat menambahkan baris berikut secara manual ke file Package.appxmanifest proyek Anda.

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

Mengaktifkan penemuan lintas pengguna di perangkat

Sesi Jarak Jauh diarahkan untuk menyambungkan beberapa pengguna yang berbeda, sehingga perangkat yang terlibat harus mengaktifkan Berbagi Lintas Pengguna. Ini adalah pengaturan sistem yang dapat dikueri dengan metode statis di kelas RemoteSystem :

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".
}

Untuk mengubah pengaturan ini, pengguna harus membuka aplikasi Pengaturan . Di menu BerbagiPengalaman> Bersama Sistem>di seluruh perangkat, ada kotak drop-down di mana pengguna dapat menentukan perangkat mana yang dapat dibagikan sistem mereka.

halaman pengaturan pengalaman bersama

Sertakan namespace yang diperlukan

Untuk menggunakan semua cuplikan kode dalam panduan ini, Anda akan memerlukan pernyataan berikut using dalam file kelas Anda.

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

Membuat sesi jarak jauh

Untuk membuat instans sesi jarak jauh, Anda harus memulai dengan objek RemoteSystemSessionController . Gunakan kerangka kerja berikut untuk membuat sesi baru dan menangani permintaan gabungan dari perangkat lain.

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
    }
}

Membuat undangan sesi jarak jauh saja

Jika Anda ingin menjaga agar sesi jarak jauh Anda tidak dapat ditemukan secara publik, Anda dapat membuatnya hanya mengundang. Hanya perangkat yang menerima undangan yang dapat mengirim permintaan gabungan.

Prosedur ini sebagian besar sama seperti di atas, tetapi saat membuat instans RemoteSystemSessionController , Anda akan meneruskan objek RemoteSystemSessionOptions yang dikonfigurasi.

// 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);

//...

Untuk mengirim undangan, Anda harus memiliki referensi ke sistem jarak jauh penerima (diperoleh melalui penemuan sistem jarak jauh normal). Cukup teruskan referensi ini ke metode SendInvitationAsync objek sesi. Semua peserta dalam sesi memiliki referensi ke sesi jarak jauh (lihat bagian berikutnya), sehingga setiap peserta dapat mengirim undangan.

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

Menemukan dan bergabung dengan sesi jarak jauh

Proses penemuan sesi jarak jauh ditangani oleh kelas RemoteSystemSessionWatcher dan mirip dengan menemukan sistem jarak jauh individual.

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();
}

Ketika instans RemoteSystemSessionInfo diperoleh, instans ini dapat digunakan untuk mengeluarkan permintaan gabungan ke perangkat yang mengontrol sesi yang sesuai. Permintaan gabungan yang diterima akan secara asinkron mengembalikan objek RemoteSystemSessionJoinResult yang berisi referensi ke sesi yang bergabung.

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.
    }
}

Perangkat dapat digabungkan ke beberapa sesi secara bersamaan. Untuk alasan ini, mungkin diinginkan untuk memisahkan fungsionalitas bergabung dari interaksi aktual dengan setiap sesi. Selama referensi ke instans RemoteSystemSession dipertahankan di aplikasi, komunikasi dapat dicoba selama sesi tersebut.

Berbagi pesan dan data melalui sesi jarak jauh

Terima pesan

Anda dapat bertukar pesan dan data dengan perangkat peserta lain dalam sesi dengan menggunakan instans RemoteSystemSessionMessageChannel , yang mewakili saluran komunikasi di seluruh sesi tunggal. Segera setelah diinisialisasi, ia mulai mendengarkan pesan masuk.

Catatan

Pesan harus diserialisasikan dan dideserialisasi dari array byte saat mengirim dan menerima. Fungsionalitas ini disertakan dalam contoh berikut, tetapi dapat diimplementasikan secara terpisah untuk modularitas kode yang lebih baik. Lihat contoh aplikasi) untuk contoh ini.

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
        //...
    };
}

Mengirim pesan

Saat saluran dibuat, mengirim pesan ke semua peserta sesi sangat mudah.

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);
}

Untuk mengirim pesan hanya kepada peserta tertentu, Anda harus terlebih dahulu memulai proses penemuan untuk memperoleh referensi ke sistem jarak jauh yang berpartisipasi dalam sesi. Ini mirip dengan proses menemukan sistem jarak jauh di luar sesi. Gunakan instans RemoteSystemSessionParticipantWatcher untuk menemukan perangkat peserta sesi.

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();
}

Saat daftar referensi ke peserta sesi diperoleh, Anda dapat mengirim pesan ke sekumpulan mereka.

Untuk mengirim pesan ke satu peserta (idealnya dipilih di layar oleh pengguna), cukup teruskan referensi ke metode seperti berikut ini.

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);
}

Untuk mengirim pesan ke beberapa peserta (idealnya dipilih di layar oleh pengguna), tambahkan mereka ke objek daftar dan teruskan daftar ke metode seperti berikut ini.

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);   
}