Ronny vdb
Ronny vdb

Reputation: 2474

Nodejs recieve TCP response from non-nodejs client

I am creating a web app that needs to connect with a thirdparty software over TCP.

I have no problems sending data from Nodejs to the software over tcp with the following command:

var client = net.connect({host: [IP], port: [PORT]}, function() { //'connect' listener;
      client.write('[DATA TO SEND]');
    });

The thirdparty software returns a response to data sent. The problem is that the software does not send a specific event, so something like this wont work:

//THIS WILL NOT WORK, NO EVENT IS SENT FROM THIRD-PARTY SOFTWARE:    
client.on('data', function(data) {
        console.log(data.toString());
        client.end();
      });

Is it possible to get the response from a TCP request without events? Any suggestions would be greatly appreciated! TIA!

This is how I connect to the third party software VIA VB:

   'Connects to SOFTWARE
    Public Function Connect() As Boolean

        mTcpClient = New TcpClient
        Try
            mTcpClient.Client.Connect(Host, Port)
            '   RaiseEvent tcpConnectionStatus(Host, Port, True)
            dashboardAlerts.updateParameterStatus("engineStatus", "OK")
            Return True
        Catch ex As Exception
            RaiseEvent connectionError()
            dashboardAlerts.updateParameterStatus("engineStatus", "ERROR")
            Return False
        End Try

    End Function


    Public Sub Disconnect()

        mTcpClient.Client.Disconnect(True)
        RaiseEvent tcpConnectionStatus(Host, Port, False)

    End Sub

    'Sends command to engine via TCP
    Public Sub Send(ByVal Command As String)

        If Not mTcpClient.Client.Connected Then
            Exit Sub
        End If

        Command &= Chr(0)

        Dim mBytes() As Byte
        mBytes = System.Text.Encoding.UTF8.GetBytes(vizCommand)

        Try
            mTcpClient.Client.Send(mBytes, mBytes.Length, SocketFlags.None)
            dashboardAlerts.updateParameterStatus("Status", "OK")
        Catch ex As Exception
            dashboardAlerts.updateParameterStatus("Status", "ERROR")
            'error
        End Try
    End Sub

    'Reads data from TCP connection buffer
    Public Function Receive() As String

        Dim mBytesToRead As Integer = mTcpClient.Available
        If mBytesToRead = 0 Then
            Return "Nothing to read"
        End If

        Dim mBytes(mBytesToRead) As Byte

        Try
            mTcpClient.Client.Receive(mBytes, mBytesToRead, SocketFlags.None)
        Catch ex As Exception
            'Error
        End Try

        Return System.Text.Encoding.UTF8.GetString(mBytes)

    End Function


    '------------------  LISTENER -----------------------------------------

    'Starts software listener
    Public Function listenToSoftware() As Boolean

        If Not isListening Then
            listenerBackgroundWorker = New BackgroundWorker
            listenerBackgroundWorker.WorkerSupportsCancellation = True
            ' RaiseEvent tcpConnectionStatus(Host, Port, True)
            listenerBackgroundWorker.RunWorkerAsync()
        End If
        Return True

    End Function

    'Starts listening when backgroundworker starts
    Sub startListener() Handles listenerBackgroundWorker.DoWork

        Dim myTcpListener As TcpListener
        Try
            myTcpListener = New TcpListener(System.Net.IPAddress.Parse(Host), Port)
            isListening = True
            Console.WriteLine("Waiting for connection...")

        Catch exp As Exception
            dashboardAlerts.updateParameterStatus("engineStatus", "ERROR")
            '   box(exp.Message & ":" & exp.StackTrace)
            serviceLog.addToLog("Error creating engine listener: " & exp.Message, serviceLog.logLevelOptions.OnlylogFile)
            Exit Sub
        End Try

        'Start listening
        myTcpListener.Start()

        'Blocking - till connection is made
        Dim isLoop As Boolean = True
        Dim myCompleteMessage As StringBuilder = New StringBuilder()

        'when connection is made, reads data
        While (isLoop)
            Try
                Dim networkStream As NetworkStream
                Dim tcpClient As TcpClient
                If myTcpListener.Pending Then
                    'Accept the pending client connection and return a TcpClient initialized for communication. 
                    tcpClient = myTcpListener.AcceptTcpClient()
                    'Get the stream
                    networkStream = tcpClient.GetStream()
                    ' Read the stream 
                    If networkStream.CanRead Then
                        Dim myReadBuffer(1024) As Byte

                        Dim numberOfBytesRead As Integer = 0

                        ' Incoming message may be larger than the buffer size. 
                        Do
                            numberOfBytesRead = networkStream.Read(myReadBuffer, 0, myReadBuffer.Length)
                            myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead))
                        Loop While networkStream.DataAvailable

                        isLoop = False
                    Else
                        Console.WriteLine("Sorry.  You cannot read from this NetworkStream.")
                    End If

                    networkStream.Close()
                    tcpClient.Close()
                End If
            Catch ex As Exception
                serviceLog.addToLog("Error in TCP  listener: " & ex.Message, serviceLog.logLevelOptions.OnlylogFile)
            End Try

        End While

        myTcpListener.Stop()
        CancelListener()
        isListening = False

        'Checks if there is Null (chr(0)) in the end, and removes it
        Dim vizMessage As String = myCompleteMessage.ToString
        If vizMessage.Contains(Chr(0)) Then
            vizMessage = vizMessage.Remove(vizMessage.IndexOf(Chr(0)))
        End If

        dashboardAlerts.updateParameterStatus("engineStatus", "OK")

        RaiseEvent dataReceived(vizMessage)

    End Sub


    'When listen is complete (recieved answer)
    Private Sub searchBackgroundWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _
                                                           Handles listenerBackgroundWorker.RunWorkerCompleted

        listenerBackgroundWorker.Dispose()

    End Sub

    'When listen is disposed(canceled) 
    Private Sub searchBackgroundWorker_RunWorkerDisposed() Handles listenerBackgroundWorker.Disposed

        'RaiseEvent tcpConnectionStatus(Host, Port, False)

    End Sub


    'Cancels current listen thread
    Sub CancelListener()

        If isListening Then
            listenerBackgroundWorker.CancelAsync()
            listenerBackgroundWorker.Dispose()
            Console.WriteLine(vbLf & "listener Cancelled")
        End If

        ' RaiseEvent reportProductionComplete("Canceled")

    End Sub


#Region "Thread and events"

    'When check engines' timer ticks
    Private Sub timerCheckengines_Tick(sender As Object, e As EventArgs) Handles timerCheckConnection.Elapsed

        timerCheckConnection.Stop()   'Stops timer while check engines
        startConnectionCheck()        'Invokes thread

    End Sub


    'Starts the actual thread
    Private Sub startConnectionCheck()

        connectionBackgroundWorker = New BackgroundWorker
        Me.connectionBackgroundWorker.RunWorkerAsync()    'Starts engines check thread

    End Sub

Upvotes: 0

Views: 371

Answers (1)

mscdex
mscdex

Reputation: 106696

The data event is a local, node thing. It gets emitted when data arrives on the socket and is not something that the remote end somehow triggers explicitly. FWIW in addition to listening for data events, you can also use client.read(..) and the readable event to pull data from the socket.

Upvotes: 2

Related Questions