maldahleh
maldahleh

Reputation: 313

Monitor TCP/IP stream

I am interested in learning Vapor, so I decided to work on a website that displays government issued weather alerts. Alert distribution is done via a TCP/IP data stream (streaming1.naad-adna.pelmorex.com port 8080).

What I have in mind is to use IBM's BlueSocket (https://github.com/IBM-Swift/BlueSocket) to create a socket, though after this point, I gave it a bit of thought but was unable to come to a conclusion on what the next steps would be.

Alerts are streamed over the data stream, so I am aware the socket would need to be opened and listened on but wasn't able to get to much past that.

A few things with the data stream are that the start and end of an alert is detected using the start and end tags of the XML document (alert and /alert). There are no special or proprietary headers added to the data, it's only raw XML. I know some alerts also include an XML declaration so I assume the encoding should be taken into account if the declaration is available.

I was then thinking of using XMLParser to parse the XML and use the data I am interested in from the alert.

So really, the main thing I am struggling with is, when the socket is open, what would be the method to listen to it, determine the start and end of the alert and then pass that XML alert for processing.

I would appreciate any input, I am also not restricted to BlueSocket so if there is a better option for what I am trying to achieve, I would be more than open to it.

Upvotes: 0

Views: 453

Answers (1)

Mrwerdo
Mrwerdo

Reputation: 388

So really, the main thing I am struggling with is, when the socket is open, what would be the method to listen to it, determine the start and end of the alert and then pass that XML alert for processing.

The method that you should use is read(into data: inout Data). It stores any available data that the server has sent into data. There are a few reasons for this method to fail, such as the connection disconnecting.

Here's an example of how to use it:

import Foundation
import Socket

let s = try Socket.create()

try s.connect(to: "streaming1.naad-adna.pelmorex.com", port: 8080)

while true {
    if try Socket.wait(for: [s], timeout: 0, waitForever: true) != nil {
        var alert = Data()

        try s.read(into: &alert)

        if let message = String(data: alert, encoding: .ascii) {
            print(message)
        }
    }
}

s.close()
  1. First create the socket. The default is what we want, a IPv4 TCP Stream.
  2. Second connect() to the server using the hostname and port. Without this step, the socket isn't connected and cannot receive or send any data.
  3. wait() until hostname has sent us some data. It returns a list of sockets that have data available to read.
  4. read() the data, decode it and print it. By default this call will block if there is no data available on the socket.
  5. close() the socket. This is good practice.

You might also like to consider thinking about:

  • non blocking sockets
  • error handling
  • streaming (a single call to read() might not give a complete alert).

I hope this answers your question.

Upvotes: 1

Related Questions