Forum Discussion

bosborne's avatar
bosborne
Visitor
11 years ago

Response from input query?

I've been reading thru the External Control Guide (http://sdkdocs.roku.com/display/sdkdoc/ ... trol+Guide). I'm looking for ways to control a Roku thru the network to always make sure it's launched into a specific app playing a live video stream. It will be attached to a public TV and act as a digital signage system.

One concern would be how to monitor the system remotely, to make sure the video is being played out. The complicated solution is to have the app ping some web service periodically, and when it stops pinging, that means the video stopped play out and to re-launch the channel remotely.

I'm looking to see if I could ping the Roku instead, by sending it an input query and getting some response back. However, the external control guide doesn't make any mention of getting a response from input commands sent to the app.

Does anyone know if that's possible, or have some suggestions for what I'm trying to accomplish?

4 Replies

  • I'm not sure if the input parameters supply the sending IP, but it could be manually included by you and then the Roku could use sockets to send a blind message back (since what you'd send is itself an acknowledgment it shouldn't expect or wait for one back).
  • You could ping your channel using sockets, sending a request to the channel from an external client application and getting a response back. Note that If the client application is not running on the same local network as the Roku, the channel user would have to allow access through their firewall to the Roku channel's receiving port.

    If you want to explore this further, I can post some code I have that does this.
  • Hi,

    Ok, so I could ping the channel, but how would the channel respond? Some code example would be nice, thanks
  • This should get you started. This Roku channel code simply listens for a request sent to port 42424 from a client then echoes the request back to the client:


    Sub Main ()
    port = CreateObject ("roMessagePort")
    ui = CreateObject ("roVideoScreen")
    ui.SetMessagePort (port)
    ui.SetCertificatesFile ("common:/certs/ca-bundle.crt")
    ui.SetLoop (True)
    ui.SetContent ({
    StreamFormat: "mp4",
    Stream: {
    Url: "https://ia600408.us.archive.org/26/items/BigBuckBunny_328/BigBuckBunny_512kb.mp4",
    Bitrate: 581,
    Quality: False,
    StreamType: "mp4"
    }
    })
    ui.Show ()

    alive = aliveInit (port)

    While True
    msg = Wait (0, port)
    If Type (msg) = "roVideoScreenEvent"
    Print "roVideoScreenEvent"
    ' Handle roVideoScreenEvent here ...
    Else If Type (msg) = "roSocketEvent"
    alive.processEvent (msg)
    EndIf
    End While

    End Sub

    ' Return an 'alive' object, which has a 'processEvent' method to handle socket event completions
    Function aliveInit (port As Object) As Object
    this = {}

    ' Use the same port used by the UI component
    this.port = port

    ' Allocate a byte array for receiving data from, or sending data to, the client
    this.buffer = CreateObject ("roByteArray")
    this.bufSize = 512
    this.buffer [this.bufSize - 1] = 0 ' Ensure space allocated in buffer

    ' Create a connnection-oriented stream socket
    this.listenSocket = CreateObject ("roStreamSocket")

    ' Associate the message port with the socket
    this.listenSocket.SetMessagePort (port)

    ' Define the socket address which will be bound with the socket
    listenAddress = CreateObject ("roSocketAddress")

    ' Define which port will be used to listen for incoming connections
    listenAddress.SetPort (42424)

    ' Bind the socket address with the socket
    this.listenSocket.SetAddress (listenAddress)

    ' Ensure that a socket event will be generated when the socket becomes readable
    this.listenSocket.NotifyReadable (True)

    ' Cause the bound socket to enter the listening state
    this.listenSocket.Listen (2)

    ' Check that the socket is in the listening state
    If Not this.listenSocket.IsListening ()
    Print "Socket is not listening"
    Return Invalid
    EndIf

    ' Socket object for the socket returned by a connection
    this.connectionSocket = Invalid

    ' Handle an roSocketEvent completion
    this.processEvent = Function (msg As Object) As Void
    ' Socket event-handling loop
    If m.listenSocket.IsListening () And m.listenSocket.eOK ()
    ' If the event occurs on the listening socket, it is for a new connection,
    ' otherwise for an existing connection
    If msg.GetSocketID () = m.listenSocket.GetID () And m.listenSocket.IsReadable ()
    ' New connection
    If m.connectionSocket <> Invalid
    ' If there is already an existing connection, terminate it
    Print "Terminating existing connection"
    m.connectionSocket.Close ()
    m.connectionSocket = Invalid
    EndIf
    ' Accept the new connection
    m.connectionSocket = m.listenSocket.Accept ()
    If m.connectionSocket = Invalid
    Print "Accept failed"
    Else
    Print "Accepted new connection"
    m.connectionSocket.NotifyReadable (True)
    m.connectionSocket.SetMessagePort (m.port)
    EndIf
    Else If msg.GetSocketId () = m.connectionSocket.GetID () And m.connectionSocket.IsReadable ()
    ' Existing connection
    If m.connectionSocket.IsReadable ()
    ' Read data from the client
    recvLen = m.connectionSocket.Receive (m.buffer, 0, m.bufSize - 1)
    Print "Bytes received: "; recvLen
    If recvLen > 0
    ' Null terminate the input data so it can be printed
    m.buffer [recvLen] = 0
    Print "Echo input: "; m.buffer.ToAsciiString ()
    ' Send data back to the client
    m.connectionSocket.Send (m.buffer, 0, recvLen)
    EndIf
    EndIf
    If recvLen = 0 Or Not m.connectionSocket.eOK ()
    m.connectionSocket.Close ()
    m.connectionSocket = Invalid
    EndIf
    Else
    Print "Unknown connection"
    EndIf
    EndIf

    ' Close the socket if something went wrong
    If Not m.listenSocket.IsListening () Or Not m.listenSocket.eOK ()
    Print "Socket loop exited"
    m.listenSocket.Close ()
    If m.connectionSocket <> Invalid
    m.connectionSocket.Close ()
    EndIf
    EndIf

    End Function

    Return this
    End Function


    Here's some Python client code that just sends a "Hello" message to the Roku channel then prints out the echoed response:


    import socket

    # create an INET, STREAMing socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # now connect to the Roku on port 42424
    s.connect(('192.168.0.6', 42424))

    # send a poll request to the Roku
    s.send(b'Hello')

    # receive a response from the Roku
    response = s.recv(512)

    # print the Roku's response
    print (response)

    # terminate the socket
    s.shutdown(socket.SHUT_RDWR)
    s.close()