Forum Discussion

scaper12123's avatar
9 years ago

Can't set the port?!

in a recent change in the implimentation of my program, I've come across an absurd issue where I cannot set a roMessagePort to a variable I'm using to obtain a json string from a url. This is a vital part of my program that worked perfectly fine until this most recent change. If somebody could help me figure out what's gone wrong, I would appreciate it. I am absolutely clueless here!

[spoiler=the function involving the issue:1rzxtv5u]
Function GetJson(url as String) as string
data = CreateObject("roString")
port = CreateObject("roMessagePort")
urlLink = CreateObject("roUrlTransfer")
urlLink.SetMessagePort(port) 'the function crashes at this line, saying
urlLink.setUrl(url) '"dot opperator attempted with invalid brightscript component or interface reference"
urlLink.SetCertificatesFile("common:/certs/ca-bundle.crt")
urlLink.InitClientCertificates()

if(urlLink.AsyncGetToString())
finished = False
while not finished
msg = wait(0, port)
if msg = invalid
finished = True
urlLink.AsyncCancel()
else
if type(msg) = "roUrlEvent"
finished = True
if msg.GetInt() = 1
response = msg.GetResponseCode()
if response <> 200
print "failure! response code "; response
else
data = msg.GetString()
end if
end if
else
return invalid
end if
end if
end while
end if
return data
end function
[/spoiler:1rzxtv5u]

[spoiler=code leading up to said issue:1rzxtv5u]
function GetServices()
link_str = "url removed for privacy reasons"
json_str = GetJson(link_str)
json = ParseJson(json_str)
recent = GetRecentSermons(json)
return recent
end function


sub init()
'we can add a background here
'm.top.backgroundURI= some image url

m.layoutgroup = m.top.findNode("MainScreenGroup")
m.layoutgroup.setFocus(true)

devInfo = createObject("roDeviceInfo")
UIResolution = devInfo.getUIResolution()

lgr = m.layoutgroup.boundingRect()
lglr = m.layoutgroup.localBoundingRect()
x = -lgr.x + (UIResolution.width - lglr.width) / 2
y = -lgr.y + (UIResolution.height - lglr.height) / 2
m.layoutgroup.translation = [x, y]

m.services = GetServices()
...
end sub[/spoiler:1rzxtv5u]

[spoiler=Juuuuuuuust in case, this is the xml material involved:1rzxtv5u]<?xml version="1.0" encoding="utf-8"?>
<component name="MainScreen" extends="Scene">

<script type="text/brightscript" uri="pkg:/components/MainScreen.brs" />
<script type="text/brightscript" uri="pkg:/source/CreateLatestMenus.brs" />
<script type="text/brightscript" uri="pkg:/source/CreateLiveMenu.brs" />
<script type="text/brightscript" uri="pkg:/source/CreateRecentMenu.brs" />
<script type="text/brightscript" uri="pkg:/source/GetServices.brs" />
<script type="text/brightscript" uri="pkg:/source/GetTime.brs" />


<children>

<Group id ="MainScreenGroup">

<LayoutGroup
layoutDirection ="vert"
vertAlignment="center"
itemSpacings="[10]"
addItemSpacingAfterChild="true" >

<Button id="front"
text="Watch live service"
minWidth="1010"
height ="200"
showFocusFootprint="true"
/>

<LayoutGroup
layoutDirection ="horiz"
itemSpacings="10"
addItemSpacingAfterChild="true" >

<ButtonGroup id="buttonPairLeft"
rightJustify ="false"
minWidth ="500"
buttonHeight ="150"
buttons='["Recent Melbourne Services", "Recent Viera Services"]'
/>

<ButtonGroup id="buttonPairRight"
rightJustify ="false"
minWidth ="500"
buttonHeight ="150"
buttons='["Most Recent Sermons", "Sermons By Series"]'
/>

</LayoutGroup>

</LayoutGroup>

</Group>

</children>

</component>[/spoiler:1rzxtv5u]
  • TheEndless's avatar
    TheEndless
    Channel Surfer
    You can't create an roUrlTransfer object in the render thread. It can only be created in a Task thread.
  • "TheEndless" wrote:
    You can't create an roUrlTransfer object in the render thread. It can only be created in a Task thread.


    so how would I call it then? Do I have to do it in a main function as opposed to calling it through xml?
  • TheEndless's avatar
    TheEndless
    Channel Surfer
    You'd need to create a Task that makes the request and observe a field on it to get the result.
  • "TheEndless" wrote:
    You'd need to create a Task that makes the request and observe a field on it to get the result.


    Well, I have absolutely no clue how to do that and looking it up in the SDK documentation was very intimidating, so I moved the function calls to the main function and that seemed to sort the problem.

    Except now I'm having the same issue with another function when I try to set a message port. Can I not set message ports either?
  • "TheEndless" wrote:
    Here's an example of downloading content in SceneGraph: https://sdkdocs.roku.com/display/sdkdoc ... er+Content

    And here's a list of B/S components that can and can't be used in SceneGraph: https://sdkdocs.roku.com/display/sdkdoc ... pt+Support
    This indicates that roMessagePort can't be created in SceneGraph. It can definitely be used in a Task script, but probably not in the render thread.


    figures. This complicates my work then. Thank you; this will require a lot of reading for me to get this fixed.
  • "scaper12123" wrote:
    figures. This complicates my work then. Thank you; this will require a lot of reading for me to get this fixed.

    Alternatively, do not use sg* but use ro* components (i.e. non-scenical)