En utilisant ThreadPool.QueueUserWorkItem pour ouvrir une connexion TcpClient et lire des données dans ASP.NET et SignalR

StackOverflow https://stackoverflow.com/questions/8373081

Question

J'ai lu quelques messages sur SignalR et pensé pour un projet de test amusant que je pouvais créer une application Web pour interroger mon onkyo récepteur pour le statut et afficher les résultats dans un navigateur. Pour un premier test, je suis en mesure d'envoyer avec succès l'arrière heure actuelle sur le serveur au client en utilisant ce code dans Application_Start:

ThreadPool.QueueUserWorkItem(_ =>
{               
    dynamic clients = Hub.GetClients<KudzuHub>();
    while (true)
    {                
        clients.addMessage(DateTime.Now.ToString());

        Thread.Sleep(1000);
    }
});   

Dans le javascript client, j'ai le code suivant:

// Proxy created on the fly
var kHub = $.connection.kudzuHub;

// Declare a function on the hub so that the server can invoke it
kHub.addMessage = function (message) {
    console.log('message added');
    $('#messages').append('<li>' + message + '</li>');
};

// start the connection
$.connection.hub.start();

Donc tout cela fonctionne très bien. Chaque seconde, je reçois un nouvel élément de liste contenant la date actuelle du serveur et le temps.

Maintenant, quand j'ajouter ce code pour lire les données du récepteur Onkyo, il se casse: (toujours en Application_Start)

ThreadPool.QueueUserWorkItem(_ =>
{  
    dynamic clients = Hub.GetClients<KudzuHub>();
    try
    {
        while (true)
        {
            string host = ConfigurationManager.AppSettings["receiverIP"].ToString();
            int port = Convert.ToInt32(ConfigurationManager.AppSettings["receiverPort"]);

            TcpClient tcpClient = new TcpClient(host, port);

            NetworkStream clientSockStream = tcpClient.GetStream();

            byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
            clientSockStream.Read(bytes, 0, (int)tcpClient.ReceiveBufferSize);

            tcpClient.Close();

            clients.addMessage(System.Text.Encoding.ASCII.GetString(bytes));
            Thread.Sleep(50);
        }
    }
    catch (SocketException ex)
    {
        // do something to handle the error
    }

});

I a établi un point d'arrêt et un pas par le code. Il arrive à cette ligne, puis retourne.

clientSockStream.Read(bytes, 0, (int)tcpClient.ReceiveBufferSize);

Il ne se termine jamais le reste du code pour envoyer le message au client. Qu'est-ce que je fais mal?

Merci.

Était-ce utile?

La solution

Je ferais des changements structurels à votre boucle pour permettre au récepteur de répondre, supprimer les frais généraux de la récupération de la configuration toutes les 50 millisecondes, et le nettoyage du flux de réseau ouvert:

ThreadPool.QueueUserWorkItem(_ =>
{  
    dynamic clients = Hub.GetClients<KudzuHub>();
    TcpClient tcpClient = null;
    NetworkStream clientSockStream = null;

    try
    {
        string host = ConfigurationManager.AppSettings["receiverIP"].ToString();
        int port = Convert.ToInt32(ConfigurationManager.AppSettings["receiverPort"]);

        while (true)
        {
            if (tcpClient == null) {
              tcpClient = new TcpClient(host, port);
              clientSockStream = tcpClient.GetStream();
            }

            if (clientSockStream.CanRead) {
                byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
                try {
                   clientSockStream.Read(bytes, 0, (int)tcpClient.ReceiveBufferSize);
                } catch (Exception ex) {
                  // Add some debug code here to examine the exception that is thrown
                }

                tcpClient.Close();
                // Closing the client does not automatically close the stream
                clientSockStream.Close();

                tcpClient = null;
                clientSockStream = null;

                clients.addMessage(System.Text.Encoding.ASCII.GetString(bytes));
            }
            Thread.Sleep(50);
        }
    }
    catch (SocketException ex)
    {
        // do something to handle the error
    } finally {
       if (tcpClient != null) {
         tcpClient.Close();
         clientSockStream.Close();
       }
    } 

});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top