Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O recurso Sessões Remotas permite que um aplicativo se conecte a outros dispositivos por meio de uma sessão, seja para mensagens explícitas de aplicativo ou para troca intermediada de dados gerenciados pelo sistema, como o SpatialEntityStore para compartilhamento holográfico entre dispositivos Windows Holographic.
Sessões remotas podem ser criadas por qualquer dispositivo Windows e qualquer dispositivo Windows pode solicitar a junção (embora as sessões possam ter visibilidade somente de convite), incluindo dispositivos conectados por outros usuários. Este guia fornece código de exemplo básico para todos os principais cenários que fazem uso de sessões remotas. Esse código pode ser incorporado em um projeto de aplicativo existente e modificado conforme necessário. Para obter uma implementação de ponta a ponta, consulte o aplicativo de exemplo do Quiz Game).
Configuração preliminar
Adicionar a funcionalidade de sistema remoto
Para que seu aplicativo inicie um aplicativo em um dispositivo remoto, você deve adicionar a funcionalidade remoteSystem ao manifesto do pacote do aplicativo. Você pode usar o designer de manifesto do pacote para adicioná-lo, selecionando Sistema Remoto na guia Capacidades, ou pode adicionar manualmente a linha a seguir ao arquivo Package.appxmanifest do projeto.
<Capabilities>
<uap3:Capability Name="remoteSystem"/>
</Capabilities>
Habilitar a descoberta entre usuários no dispositivo
As Sessões Remotas são voltadas para conectar vários usuários diferentes, portanto, os dispositivos envolvidos precisarão ter o compartilhamento entre usuários habilitado. Essa é uma configuração do sistema que pode ser consultada com um método estático na classe
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".
}
Para alterar essa configuração, o usuário deve abrir Configurações. No menu "Sistema >Experiências Compartilhadas>Compartilhar entre dispositivos", há uma caixa suspensa na qual o usuário pode especificar com quais dispositivos seu sistema pode compartilhar.
Incluir os namespaces necessários
Para usar todos os trechos de código neste guia, você precisará das declarações a seguir using em seus arquivos de classe.
using System.Runtime.Serialization.Json;
using Windows.Foundation.Collections;
using Windows.System.RemoteSystems;
Criar uma sessão remota
Para criar uma instância de sessão remota, você deve começar com um objeto RemoteSystemSessionController . Use a estrutura a seguir para criar uma nova sessão e manipular solicitações de junção de outros dispositivos.
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
}
}
Tornar uma sessão remota exclusiva para convidados
Se você quiser impedir que sua sessão remota seja publicamente detectável, você pode torná-la somente para convidados. Somente os dispositivos que recebem um convite poderão enviar solicitações de junção.
O procedimento é basicamente o mesmo que acima, mas ao construir a instância RemoteSystemSessionController , você passará um objeto RemoteSystemSessionOptions configurado.
// 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);
//...
Para enviar um convite, você deve ter uma referência ao sistema remoto de recebimento (adquirida por meio do processo padrão de descoberta do sistema remoto). Basta passar essa referência para o método SendInvitationAsync do objeto de sessão. Todos os participantes de uma sessão têm uma referência à sessão remota (consulte a próxima seção), para que qualquer participante possa enviar um convite.
// "currentSession" is a reference to a RemoteSystemSession.
// "guestSystem" is a previously discovered RemoteSystem instance
currentSession.SendInvitationAsync(guestSystem);
Descobrir e ingressar em uma sessão remota
O processo de descoberta de sessões remotas é tratado pela classe RemoteSystemSessionWatcher e é semelhante à descoberta de sistemas remotos individuais.
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();
}
Quando uma instância RemoteSystemSessionInfo é obtida, ela pode ser usada para emitir uma solicitação de junção ao dispositivo que controla a sessão correspondente. Uma solicitação de junção aceita retornará de forma assíncrona um objeto RemoteSystemSessionJoinResult que contém uma referência à sessão ingressada.
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.
}
}
Um dispositivo pode ser unido a várias sessões ao mesmo tempo. Por esse motivo, pode ser desejável separar a funcionalidade de junção da interação real com cada sessão. Desde que uma referência à instância
Compartilhar mensagens e dados por meio de uma sessão remota
Receber mensagens
Você pode trocar mensagens e dados com outros dispositivos participantes na sessão usando uma instância RemoteSystemSessionMessageChannel , que representa um único canal de comunicação em toda a sessão. Assim que é inicializado, ele começa a ouvir mensagens de entrada.
Observação
As mensagens devem ser serializadas e desserializadas de matrizes de bytes ao enviar e receber. Essa funcionalidade está incluída nos exemplos a seguir, mas pode ser implementada separadamente para melhor modularidade de código. Consulte o aplicativo de exemplo) para obter um exemplo disso.
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
//...
};
}
Enviar mensagens
Quando o canal é estabelecido, enviar uma mensagem para todos os participantes da sessão é simples.
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);
}
Para enviar uma mensagem apenas para determinados participantes, primeiro você deve iniciar um processo de descoberta para adquirir referências aos sistemas remotos participantes da sessão. Isso é semelhante ao processo de descoberta de sistemas remotos fora de uma sessão. Use uma instância remoteSystemSessionParticipantWatcher para localizar os dispositivos participantes de uma sessão.
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();
}
Quando uma lista de referências aos participantes da sessão é obtida, você pode enviar uma mensagem para qualquer conjunto deles.
Para enviar uma mensagem a um único participante (idealmente selecionado na tela pelo usuário), basta passar a referência para um método como o seguinte.
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);
}
Para enviar uma mensagem a vários participantes (idealmente selecionado na tela pelo usuário), adicione-os a um objeto de lista e passe a lista para um método como o seguinte.
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);
}
Tópicos relacionados
- aplicativos e dispositivos conectados (Project Rome)
- referência da API de Sistemas Remotos