Escrito usando informações de pré-lançamento
Uma das
boas coisas que temos com o Windows Phone 7 é suporte a socket. Enquanto eu
esperava ser capaz de abrir sockets para outras máquinas com servidores sendo
executados nelas, algo me pegou de surpresa; o fato de que você também pode
enviar comunicação de um telefone para outro usando UDP. Tenho que dar crédito
a Ricky_T por apontar a
presença desse recurso e postar um exemplo do código. Eu queria tentar sozinho.
Então criei uma versão do código que rodaria tanto no Windows Phone quanto no desktop
sem nenhum problema. Essa capacidade fornece várias soluções para problemas que
eu estava considerando, tais como descoberta e configuração automática para
comunicação com serviços hospedados em uma rede de usuário local.
A maior parte do código utilizada na versão
desktop e de telefones deste exemplo é idêntica; eu compartilhei alguns dos
mesmos arquivos entre os projetos. Os arquivos que não foram compartilhados nas
versões desktop e de telefones ainda são similares. O núcleo desse código está
em uma classe chamada Peer. Vamos dar uma olhada no corpo dessa classe.
//Define the port and multicast address to be used for communication
private string _channelAddress = "224.0.0.1";
private int _channelPort = 3007;
//The event to be raised when a message comes in
public event EventHandler<MessageReceivedEventArgs> MessageReceived;
//the UDP channel over which communication will occur.
private UdpAnySourceMulticastClient _channel;
//Create tje cjamme;
public void Initialize()
{
_channel = new UdpAnySourceMulticastClient(IPAddress.Parse(_channelAddress), _channelPort);
}
//Open the channel and start listening
public void Open()
{
if (_channel == null)
Initialize();
ClientState = ClientStatesEnum.Opening;
_openResult = _channel.BeginJoinGroup((result) =>
{
_channel.EndJoinGroup(result);
ClientState = ClientStatesEnum.Opened;
}, null);
Receive();
}
//The receive method is recursive. At the end of a call to receive it calls itself
//so that the class can continue listening for incoming requests.
void Receive()
{
byte[] _receiveBuffer = new byte[1024];
_channel.BeginReceiveFromGroup(_receiveBuffer, 0, _receiveBuffer.Length, (r) =>
{
if(ClientState!=ClientStatesEnum.Closing)
{
try
{
IPEndPoint source;
int size= _channel.EndReceiveFromGroup(r, out source);
OnMessageReceived(_receiveBuffer, size, source);
}
catch (Exception )
{
}
finally
{
this.Receive();
}
}
}, null);
}
public void Send(byte[] data)
{
if(ClientState==ClientStatesEnum.Opened)
{
_channel.BeginSendToGroup(data, 0, data.Length, (r) => _channel.EndSendToGroup(r),null);
}
}
Essa
classe somente envia e recebe arrays de byte. Meu único objetivo aqui era ver o
código funcionando, então existem outras considerações que decidi deixar passar
por enquanto. O cliente envia e recebe um texto puro. Antes de enviar um bloco
de texto, é necessário converter o texto para uma byte array. A classe
codificada em .NET irá fazer isso para mim. Quando uma mensagem chegar, eu
também posso usar um codificador para converter a byte array de volta para uma
string. .
Para esse programa, estou adicionando a
mensagem a ser recebida a uma lista juntamente com o endereço IP de onde ela
veio.
void _peer_MessageReceived(object sender, MessageReceivedEventArgs e)
{
Action a = () =>
{
string message = System.Text.UTF8Encoding.Unicode.GetString(e.Data, 0, e.Size);
MessageList.Add(String.Format("{0}:{1}", e.Endpoint.Address.ToString(), message));
OnIncomingMessageReceived(message, e.Endpoint.Address.ToString());
};
if (UIDispatcher == null)
a();
else
UIDispatcher.BeginInvoke(a);
}
public void SendMessage(string message)
{
byte[] encodedMessage= UTF8Encoding.Unicode.GetBytes(message);
_peer.Send(encodedMessage);
}
Quando o
código é executado em qualquer combinação de telefones múltiplos ou computadores, uma mensagem escrita em qualquer um dos dispositivos aparece em todos
eles. Legal! Agora comece a fazer bom uso disso.
?
Texto original disponível em http://j2i.net/blogengine/post/2011/06/20/Peer-Communication-on-Windows-Phone-7.aspx







