Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
JavaScript control point bindings
19-03-2012, 11:52 AM
Post: #1
JavaScript control point bindings
I'm thinking about adding a Web UI for MinimServer. If I were to use the JavaScript control point bindings for this, does that require the ohNet runtime to be installed on the browser client machine? Or is the ohNet runtime installed on the Web server that's serving the HTML/JavaScript pages?

If it's the latter (as I'd expect), how does the JavaScript code running on the client interact with the ohNet runtime running on the server? What's the bootstrapping magic that allows the client-side JavaScript code to get hold of a Library object running on the server?

Apologies if I'm unaware of some existing documentation that describes this.
Find all posts by this user
19-03-2012, 02:56 PM (This post was last modified: 20-03-2012 08:11 AM by simonc.)
Post: #2
RE: JavaScript control point bindings
To add a web UI you should have your DvDeviceStandard set its Upnp.PresentationUrl attribute. This will make your device visible in any system UI which lists UPnP devices (e.g. Network on Windows, Intel Device Spy, etc.). Selecting a device in one of these programs will typically launch your default web browser to view the device's presentation url.

To do this with ohNet, create your DvDeviceStandard to have a IResourceManager. This automatically gives it a presentation url and calls the IResourceManager's WriteResource function when a browser (or anything else) wants to view the presentation page. The aUriTail argument in WriteResource will be empty for the presentation page.

The presentation page will normally be an html file which refers to other files, including javascript, styling (.css) and images. You can refer to these using relative paths. Each of these will generate another call to your WriteResource function, with aUriTail equal to the relative path (+ name).

Web UIs typically do very little server side work. The resource writer normally just copies files from the device's file system rather than creating custom content based on device state. UIs instead contain javascript which renders different content depending on device state. ohNet proxies are used to query device state. ohNet provides proxies for audio-related services and a tool to generate any other proxies from their service xml. Pre-generated proxies are available in ohNet/OpenHome/Net/Bindings/Js/ControlPoint/Proxies. Utilities required by or supporting the proxies are available in ohNet/OpenHome/Net/Bindings/Js/ControlPoint/lib. The subscription manager is the most interesting of these; it allows changes in device state to be evented to the control point.

We have a sample resource manager (in C#) and web UI available for you to refer to. Documentation in this area is very light so feel free to come back with further questions.
Find all posts by this user
20-03-2012, 04:30 PM
Post: #3
RE: JavaScript control point bindings
Thanks very much for this! I've looked at the sample, but getting it to build and run seems like a daunting task given the ohOs and C# dependencies.

I thought it might be easier for me to start with Bindings/Js/ControlPoint/Tests in ohNet. I'm not sure how to build and run these tests, though. There's an index.html file which gives me an error if I try to open it in my browser. Could you give me a brief pointer in the right direction, please?
Find all posts by this user
20-03-2012, 04:37 PM
Post: #4
RE: JavaScript control point bindings
(20-03-2012 04:30 PM)simoncn Wrote:  I thought it might be easier for me to start with Bindings/Js/ControlPoint/Tests in ohNet. I'm not sure how to build and run these tests, though. There's an index.html file which gives me an error if I try to open it in my browser. Could you give me a brief pointer in the right direction, please?

We run it using ohnet/AllTests.py. See the JsTests() function for details.

I suspect this won't be the easiest thing to run stand-alone. You might be better editing gAllTests to contain only TestBuffer and changing build('all') (around line 42) to build('TestBuffer TestDvTestBasic') then running python AllTests.py --js.

If using python is also difficult for you, installing mono and building ohOs might start to become more attractive...
Find all posts by this user
20-03-2012, 07:30 PM
Post: #5
RE: JavaScript control point bindings
(20-03-2012 04:37 PM)simonc Wrote:  We run it using ohnet/AllTests.py. See the JsTests() function for details.

I suspect this won't be the easiest thing to run stand-alone. You might be better editing gAllTests to contain only TestBuffer and changing build('all') (around line 42) to build('TestBuffer TestDvTestBasic') then running python AllTests.py --js.

If using python is also difficult for you, installing mono and building ohOs might start to become more attractive...

I think you meant less unattractive... Smile

I tried your suggestion and I got TestBuffer to run correctly. However, TestDvTestBasic failed with the following error:

TestDvTestBasic - starting ('q' to quit)
Traceback (most recent call last):
File "AllTests.py", line 306, in <module>
JsTests()
File "AllTests.py", line 285, in JsTests
do_jstest.find_device()
File "AllTests.py", line 268, in find_device
test_devfinder = subprocess.Popen([os.path.join(self.objpath, 'TestDeviceFinder.exe'), '-l', '-s', openhome.org:service:TestBasic:1'],stdout=subprocess.PIPE, stderr=subprocess.PIPE)
File "d:\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "d:\Python27\lib\subprocess.py", line 893, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

I also tried running python AllTests.py --js without changing the AllTests.py file. This gave a different error in TestDvTestBasic:

TestDvTestBasic - starting ('q' to quit)
found device at http://127.0.0.1:55178/device-ohNetTestB.../resource/
Traceback (most recent call last):
File "AllTests.py", line 306, in <module>
JsTests()
File "AllTests.py", line 288, in JsTests
do_jstest.run_browser()
File "AllTests.py", line 273, in run_browser
subprocess.call(["%s" %(self.browser_location), "%s" %(self.launch_url)])
File "d:\Python27\lib\subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "d:\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "d:\Python27\lib\subprocess.py", line 893, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

It looks like this attempt got further, but failed because there was some problem with %(self.browser_location) or %(self.launch_url).
Find all posts by this user
20-03-2012, 08:39 PM
Post: #6
RE: JavaScript control point bindings
Looks like you also need to build TestDeviceFinder. You could add this to your custom build set if you want to skip all the other tests.

The later error may be because I forgot to tell you that the test looks for your Safari install. The test validates our WebSocket support so can only run on Safari or Chrome (the only browsers with WebSocket support by default*). We run this test automatically after each commit and found that Chrome auto-updates sometimes broke command line launching so we hard-coded the test to assume Safari.

Safari is a free install for Windows so is easy to try if you want. Or I'd quite understand if this was the point where you gave up on this 'easy' route to running sample code.

(If you do want to look at the ohOs code again, Visual Studio's Express edition would allow you to compile the code for free on Windows. The debugger here is quite limited though so you may be unable to set breakpoints in the resource manager and have to log to console - using Console.WriteLine - instead.)

* Or at least the only ones a while ago when we last tested
Find all posts by this user
20-03-2012, 09:12 PM
Post: #7
RE: JavaScript control point bindings
(20-03-2012 08:39 PM)simonc Wrote:  Looks like you also need to build TestDeviceFinder. You could add this to your custom build set if you want to skip all the other tests.

Thanks, I'll add that.

Quote:The later error may be because I forgot to tell you that the test looks for your Safari install. The test validates our WebSocket support so can only run on Safari or Chrome (the only browsers with WebSocket support by default*). We run this test automatically after each commit and found that Chrome auto-updates sometimes broke command line launching so we hard-coded the test to assume Safari.

Safari is a free install for Windows so is easy to try if you want. Or I'd quite understand if this was the point where you gave up on this 'easy' route to running sample code.

I already have Safari for Windows installed. Do I need to upgrade it to a more recent version? The version I have is 5.0.1.

Quote:(If you do want to look at the ohOs code again, Visual Studio's Express edition would allow you to compile the code for free on Windows. The debugger here is quite limited though so you may be unable to set breakpoints in the resource manager and have to log to console - using Console.WriteLine - instead.)

* Or at least the only ones a while ago when we last tested

I've got the full version of Visual Studio 2010, so that part's not an issue. Also, it's not a matter of how much time it would take me to run builds or tweak test scripts. It's much more a question of how much extra stuff / new concepts my brain can absorb at the moment. I'm almost fully occupied with fixing bugs and adding features to MinimServer, so I can only do this Web UI investigation if it's a relatively small and incremental step to what I currently know and understand about ohNet. If I have to get my mind around what's in ohOs as well (not to mention all the dependencies that it needs), that's too much for me to digest right now.
Find all posts by this user
20-03-2012, 10:07 PM (This post was last modified: 20-03-2012 10:14 PM by simonc.)
Post: #8
RE: JavaScript control point bindings
(20-03-2012 09:12 PM)simoncn Wrote:  I already have Safari for Windows installed. Do I need to upgrade it to a more recent version? The version I have is 5.0.1.

That should be a sufficiently recent version. I can't think off-hand why it'd fail, I'll need to try it from work tomorrow.

(20-03-2012 09:12 PM)simoncn Wrote:  I've got the full version of Visual Studio 2010, so that part's not an issue. Also, it's not a matter of how much time it would take me to run builds or tweak test scripts. It's much more a question of how much extra stuff / new concepts my brain can absorb at the moment. I'm almost fully occupied with fixing bugs and adding features to MinimServer, so I can only do this Web UI investigation if it's a relatively small and incremental step to what I currently know and understand about ohNet. If I have to get my mind around what's in ohOs as well (not to mention all the dependencies that it needs), that's too much for me to digest right now.

Understood. Just in case it changes your mind about the relative difficulty of using ohOs, the work involved would be
  • clone ohOs source (using command line on github)
  • clone ohDevTools repo also
  • launch visual studio command prompt (32-bit cross compile)
  • cd to ohos directory
  • run go fetch. This should fetch all ohOs' dependencies
  • run waf configure
  • run waf build. This will build all ohOs code.
  • list build\*.zip then run build\ohOs.Host.exe --install [App Manager].zip
  • run build\ohOs.Host.exe
  • In Visual Studio, select Debug -> Attach to Process and attach to one of the ohOs.Host processes
  • Set a breakpoint in WriteResource in NodeResourceManager.cs. If this shows a white circle with red outline, attach to the other ohOs.Host process and try again.
  • run Intel Device Spy and look for ohOs.AppManager. Right click on it and Display Presentation Page
  • Your breakpoint should be hit, allowing you to step through code, inspect arguments etc.
Writing this all down adds up to a longer list than I'd thought but it might be worth considering as an alternative to battling with ohNet's unit tests.
Find all posts by this user
21-03-2012, 03:07 PM
Post: #9
RE: JavaScript control point bindings
I got this to run by changing the value of my ProgramFiles environment variable. It was set to C:\Program Files, but I have Safari installed in D:\Program Files. The output was as follows:

TestDvTestBasic - starting ('q' to quit)
found device at http://127.0.0.1:55178/device-ohNetTestB.../resource/
WS: Wait for next request (or interrupt)
WS: Subscribe
WS: Wait for next request (or interrupt)
OpenHome/Network.cpp:258: Socket::Receive H = 13500432, RETURN VALUE = -1
WS: Write property update
WS: Wait for next request (or interrupt)
WS: Subscribe
WS: Wait for next request (or interrupt)
OpenHome/Network.cpp:258: Socket::Receive H = 13500432, RETURN VALUE = -1
WS: Write property update
WS: Wait for next request (or interrupt)
OpenHome/Network.cpp:258: Socket::Receive H = 13500432, RETURN VALUE = -1
WS: Write property update
WS: Write property update
WS: Wait for next request (or interrupt)
OpenHome/Network.cpp:258: Socket::Receive H = 13500432, RETURN VALUE = -1
WS: Write property update
WS: Write property update
WS: Wait for next request (or interrupt)
OpenHome/Network.cpp:258: Socket::Receive H = 13500432, RETURN VALUE = -1
WS: Write property update
WS: Write property update
WS: Wait for next request (or interrupt)
OpenHome/Network.cpp:258: Socket::Receive H = 13500432, RETURN VALUE = -1
WS: Write property update
WS: Write property update
WS: Wait for next request (or interrupt)
OpenHome/Network.cpp:258: Socket::Receive H = 13500432, RETURN VALUE = -1
WS: Write property update
WS: Write property update
WS: Wait for next request (or interrupt)
WS: Unsubscribe
WS: Wait for next request (or interrupt)
OpenHome/Network.cpp:258: Socket::Receive H = 13500432, RETURN VALUE = -1
WS: Write property update
WS: Write property update
WS: Wait for next request (or interrupt)
OpenHome/Network.cpp:258: Socket::Receive H = 13500432, RETURN VALUE = -1
WS: Exception - ReaderError
OpenHome/Network.cpp:230: Socket::Send H = 13500432, RETURN VALUE = 0, INCOMPLETE

Is this correct? I wasn't sure about the lines saying RETURN VALUE = -1, ReaderError, and INCOMPLETE.
Find all posts by this user
21-03-2012, 03:52 PM
Post: #10
RE: JavaScript control point bindings
Glad you've got it working!

Believe it or not, this is the expected type of output and probably indicates success. To double check this, have a look at ohnet/xout/ProxyJsTest.xml.

Don't worry about all the ReaderErrors etc. They're a result of this test enabling more detailed logging than any other and show an implementation detail of how the WebSocket server interrupts reads for client requests to send evented updates.
Find all posts by this user


Forum Jump: