Verwenden von Threadpool.QueueuserworkItem, um eine TCPClient -Verbindung zu öffnen und Daten in ASP.NET und SignalR zu lesen

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

Frage

Ich habe ein paar Beiträge zu SignalR gelesen und über ein lustiges Testprojekt nachgedacht, dass ich eine Webanwendung erstellen kann, um meinen Onkyo -Empfänger für den Status zu befragen und die Ergebnisse in einem Browser anzuzeigen. Für einen ersten Test konnte ich die aktuelle Zeit auf dem Server erfolgreich an den Client senden, indem ich diesen Code in Application_start verwendete:

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

        Thread.Sleep(1000);
    }
});   

Im Client JavaScript habe ich den folgenden Code:

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

Also funktioniert all das gut. Jede Sekunde erhalte ich ein neues Listenelement, das das aktuelle Datum und die Uhrzeit des Servers enthält.

Wenn ich diesen Code nun hinzufüge, um Daten vom Onkyo -Empfänger zu lesen, bricht er: (immer noch in 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
    }

});

Ich legte einen Break -Punkt ein und trat durch den Code. Es kommt zu dieser Zeile und kehrt dann zurück.

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

Es wird nie den Rest des Codes beendet, um die Nachricht an den Client zu senden. Was mache ich falsch?

Vielen Dank.

War es hilfreich?

Lösung

Ich würde einige strukturelle Änderungen an Ihrer Schleife vornehmen, damit die Empfängerzeit reagieren, den Overhead des Abrufens der Konfiguration alle 50 Millisekunden entfernen und den offenen Netzwerkstrom aufräumen:

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

});
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top