55 votes

Groupe de multidiffusion UDP sur Windows Phone 8

OK c'est celui que j'ai été à essayer de comprendre maintenant quelques jours. Nous avons une application sur Windows Phone 7 où les téléphones joindre à un groupe de multidiffusion et ensuite l'envoyer et recevoir des messages pour le groupe à parler les uns aux autres. Note: ceci est un téléphone à l'autre de la communication.

Maintenant, je vais essayer de port cette application pour Windows Phone 8 - à l'aide de la "Convertir Phone 8' fonctionnalité de Visual Studio 2012 - so far so good. Jusqu'à ce que j'essaie de tester le téléphone à la communication. Les combinés semblent rejoindre le groupe amende, et ils envoient les datagrammes OK. Ils ont même recevoir les messages qu'ils envoient le groupe - cependant, pas de combiné reçoit un message à partir d'un autre combiné.

Voici un exemple de code derrière de ma page:

// Constructor
public MainPage()
{
    InitializeComponent();
}

// The address of the multicast group to join.
// Must be in the range from 224.0.0.0 to 239.255.255.255
private const string GROUP_ADDRESS = "224.0.1.1";

// The port over which to communicate to the multicast group
private const int GROUP_PORT = 55562;

// A client receiver for multicast traffic from any source
UdpAnySourceMulticastClient _client = null;

// Buffer for incoming data
private byte[] _receiveBuffer;

// Maximum size of a message in this communication
private const int MAX_MESSAGE_SIZE = 512;

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    _client = new UdpAnySourceMulticastClient(IPAddress.Parse(GROUP_ADDRESS), GROUP_PORT);
    _receiveBuffer = new byte[MAX_MESSAGE_SIZE];

    _client.BeginJoinGroup(
        result =>
        {
            _client.EndJoinGroup(result);
            _client.MulticastLoopback = true;
            Receive();
        }, null);
}

private void SendRequest(string s)
{
    if (string.IsNullOrWhiteSpace(s)) return;

    byte[] requestData = Encoding.UTF8.GetBytes(s);

    _client.BeginSendToGroup(requestData, 0, requestData.Length,
        result =>
        {
            _client.EndSendToGroup(result);
            Receive();
        }, null);
}

private void Receive()
{
    Array.Clear(_receiveBuffer, 0, _receiveBuffer.Length);
    _client.BeginReceiveFromGroup(_receiveBuffer, 0, _receiveBuffer.Length,
        result =>
        {
            IPEndPoint source;

            _client.EndReceiveFromGroup(result, out source);

            string dataReceived = Encoding.UTF8.GetString(_receiveBuffer, 0, _receiveBuffer.Length);

            string message = String.Format("[{0}]: {1}", source.Address.ToString(), dataReceived);
            Log(message, false);

            Receive();
        }, null);
}

private void Log(string message, bool isOutgoing)
{
    if (string.IsNullOrWhiteSpace(message.Trim('\0')))
    {
        return;
    }

    // Always make sure to do this on the UI thread.
    Deployment.Current.Dispatcher.BeginInvoke(
    () =>
    {
        string direction = (isOutgoing) ? ">> " : "<< ";
        string timestamp = DateTime.Now.ToString("HH:mm:ss");
        message = timestamp + direction + message;
        lbLog.Items.Add(message);

        // Make sure that the item we added is visible to the user.
        lbLog.ScrollIntoView(message);
    });

}

private void btnSend_Click(object sender, RoutedEventArgs e)
{
    // Don't send empty messages.
    if (!String.IsNullOrWhiteSpace(txtInput.Text))
    {
        //Send(txtInput.Text);
        SendRequest(txtInput.Text);
    }
}

private void btnStart_Click(object sender, RoutedEventArgs e)
{
    SendRequest("start now");
}

Pour simplement tester la pile UDP, j'ai téléchargé l'échantillon à partir de MSDN trouvé ici et j'ai testé cela sur une paire de Windows Phone 7 appareils et qu'il fonctionne comme prévu. Puis je me suis converti à Windows Phone 8 et déployé à mes mobiles, les appareils semblent se lancer à leur égard, et l'utilisateur peut entrer leur nom. Cependant, là encore, les appareils ne peuvent pas voir ou communiquer avec d'autres appareils.

Enfin j'ai mis en place un simple test de communication à l'aide de la new DatagramSocket mise en œuvre, et de nouveau je vois initiation réussie, mais pas de l'inter-périphérique de communication.

C'est le même code-behind de la page à l'aide de la socket datagramme mise en œuvre:

// Constructor
public MainPage()
{
    InitializeComponent();
}

// The address of the multicast group to join.
// Must be in the range from 224.0.0.0 to 239.255.255.255
private const string GROUP_ADDRESS = "224.0.1.1";

// The port over which to communicate to the multicast group
private const int GROUP_PORT = 55562;

private DatagramSocket socket = null;

private void Log(string message, bool isOutgoing)
{
    if (string.IsNullOrWhiteSpace(message.Trim('\0')))
        return;

    // Always make sure to do this on the UI thread.
    Deployment.Current.Dispatcher.BeginInvoke(
    () =>
    {
        string direction = (isOutgoing) ? ">> " : "<< ";
        string timestamp = DateTime.Now.ToString("HH:mm:ss");
        message = timestamp + direction + message;
        lbLog.Items.Add(message);

        // Make sure that the item we added is visible to the user.
        lbLog.ScrollIntoView(message);
    });
}

private void btnSend_Click(object sender, RoutedEventArgs e)
{
    // Don't send empty messages.
    if (!String.IsNullOrWhiteSpace(txtInput.Text))
    {
        //Send(txtInput.Text);
        SendSocketRequest(txtInput.Text);
    }
}

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    socket = new DatagramSocket();
    socket.MessageReceived += socket_MessageReceived;

    try
    {
        // Connect to the server (in our case the listener we created in previous step).
        await socket.BindServiceNameAsync(GROUP_PORT.ToString());
        socket.JoinMulticastGroup(new Windows.Networking.HostName(GROUP_ADDRESS));
        System.Diagnostics.Debug.WriteLine(socket.ToString());
    }
    catch (Exception exception)
    {
        throw;
    }
}

private async void SendSocketRequest(string message)
{
    // Create a DataWriter if we did not create one yet. Otherwise use one that is already cached.
    //DataWriter writer;
    var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(GROUP_ADDRESS), GROUP_PORT.ToString());
    //writer = new DataWriter(socket.OutputStream);
    DataWriter writer = new DataWriter(stream);

    // Write first the length of the string as UINT32 value followed up by the string. Writing data to the writer will just store data in memory.
   // stream.WriteAsync(
    writer.WriteString(message);

    // Write the locally buffered data to the network.
    try
    {
        await writer.StoreAsync();
        Log(message, true);
        System.Diagnostics.Debug.WriteLine(socket.ToString());
    }
    catch (Exception exception)
    {
        throw;
    }
    finally
    {
        writer.Dispose();
    }
}

void socket_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    try
    {
        uint stringLength = args.GetDataReader().UnconsumedBufferLength;
        string msg = args.GetDataReader().ReadString(stringLength);

        Log(msg, false);
    }
    catch (Exception exception)
    {
        throw;
    }
}

La nuit dernière j'ai pris les combinés à la maison pour tester sur mon réseau domestique sans fil, faible et voici, je la réussite de l'appareil de communication.

Donc, pour résumer - mon héritage, Windows Phone 7 code fonctionne très bien sur mon réseau d'entreprise. Le port de Windows Phone 8 (pas de changement de code) ne pas envoyer inter-périphérique de communication. Ce code fonctionne sur mon réseau domestique. Le code s'exécute avec le débogueur et il n'y a pas de signes d'erreurs d'exceptions ou de n'importe où au cours de l'exécution.

Les appareils que j'utilise sont:

Windows Phone 7 - Nokia Lumia 900 (* 2), Le Nokia Lumia 800 (* 3) Windows Phone 8 - Nokia Lumia 920 (* 1), Nokia Limia 820 (* 2)

Ces sont tous en cours d'exécution le dernier système d'exploitation, et sont en mode développeur. Environnement de développement de Windows 8 Enterprise exécution de Visual Studio 2012 Professional

Je ne peux pas vous en dire beaucoup sur le travail de réseau sans fil - autres que le Phone 7 appareils n'ont pas de difficulté.

Comme pour la maison de réseau sans fil que j'ai utilisé, c'est juste une base de BT Broadband router avec aucun de la de "la boîte" paramètres modifiés.

Il y a clairement un problème avec la façon que les deux réseau sont configurés, mais il est aussi très clairement un problème avec la façon dont Windows Phone 8 met en œuvre messages UDP.

Toute entrée serait appréciée comme cela me rend fou maintenant.

1voto

Terraslate Points 66

J'ai remarqué que vous utilisez le bouclage. Je pense que cela signifie que lorsque vous envoyez un message à partir de votre client, vous recevrez le message que vous avez envoyé également. Cela signifie que votre gestionnaire de réception sera le feu. Il a pour effet d'effacer le tampon de réception dans une apparence de unthreadsafe de la mode. Essayez de mettre quelques try catch dans votre méthode de réception et de voir si quelque chose de fâcheux se passe, mais vous pourriez au lieu tout simplement pas l'utilisation partagée du tampon de réception, en tout cas.

1voto

HaMster Points 176

Avez-vous déjà essayé de rejoindre un autre groupe de multidiffusion? Parce que 224.0.1.1 semble être dans l'utilisation de l'IANA pour les affectations. Vous trouverez tous les ici.

Peut-être que sur Windows Phone 8, certains services est plus lié à écouter les messages entrants (par exemple, un service réseau qui est en cours d'exécution en mode noyau) et ils ne sont jamais transmis à vous.

1voto

dendini Points 727

Multidiffusion UDP fonctionne assez étrangement sous windows phone 7 de mon expérience, de sorte que vous devriez commander la même chose pour windows phone 8.

Voici mon expérience:

  1. vérifiez ce qui est officiellement pris en charge, par exemple sous Windows Phone OS 7.1 (dernier OS que j'ai essayé avant de commutation), la diffusion unique TCP, UDP unicast, et UDP multicast clients sont pris en charge.
  2. certaines versions de Windows phone permis de recevoir une session UDP uniquement si le client a d'abord ouvert et la session est reçu dans un délai de pas plus de 10 secondes, cela semble être une sorte de sécurité de chose sur Windows Phone.
  3. essayez avec différentes adresses: les adresses de multidiffusion dans la gamme de 224.0.0.0 à 224.0.0.255 inclusive sont "bien connus" réservés adresses de multidiffusion.
  4. Vérifier à la fois dans la machine virtuelle et dans un vrai téléphone de l'appareil, le comportement peut varier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X