A Fun New Direction for AppJS!

928 views
Skip to first unread message

sihorton

unread,
Sep 6, 2013, 2:13:30 AM9/6/13
to appj...@googlegroups.com
Hi AppJS Developers.

This will be a long post, take a break get a coffee and prepare yourself!

Background:
=========

I remember many years ago discovering that netscape navigator could read files directly off the local disk using the file:// protocol. At that time I was building desktop applications in visual basic. These were quite good and deeply integrated into the OS but the interface was nothing compared to dynamic html (as it was called back then in the golden olden days of the internets). Suddenly I had the opportunity to have a beautiful and flexible interface I could throw up in a couple of mins running on the desktop. Using iframes I could even list the contents of the disk and navigate through it with a nice interface. Of course it was a hack and a horrible security flaw so after a couple of years suddenly the hole was plugged and those hacks stopped working.

I have tried out many different hacks, tricks and technologies through the years always trying to reach the same goal really:- I find web technologies very natural, powerful and rapid to develop and deploy. When I find myself building a desktop application (for example a file monitor that automatically uploads changes to a remote server), then I always want to have a desktop application with full access to local disk etc, but I want the interface to be html and web technologies.

What is needed is a "browser" giving that wonderful html interface and web technologies, but it should have some security features turned off so local disk access and database is possible and it should not auto-update -- if I build an app I want it to run and work forever even if google depreciates those google gears apis I used to build an app 3 years ago.

AppJS:
=====

When I discovered AppJS I found a great solution. NodeJS is very powerful and awesome for async programming and chromium is a very modern and powerful browser and gives a wonderful interface development platform. The magic is that both nodejs and chromium use the same v8 javascript engine, so with appjs you bridge the two v8 contexts and get the wonderful solution we all know and love.

Technical Limitation:
===============
Unfortunately we have reached a technical limitation in appjs development. As wonderful, revolutionary and just plain awesome that bridging the nodejs and chromium v8 contexts was there was an unfortunate and unexpected side effect. Since both contexts are running in the same process, heavy operations in the browser will block operations in nodejs. Likewise heavy nodejs operations will block chromium. This is very unexpected to web developers and therefore causes problems. If for example you use CSS3 animations to spin and move items in the interface around then the animations become juddery and pause as nodejs performs heavy operations. Everyone just thinks hey it should not be like that!

The obvious solution is to put nodejs and chromium in their own processes or threads so animations can run at the same time as nodejs is doing whatever the application needs. The async nature of javascript (it does not support threads as native objects but uses callbacks instead) means that altering appjs to run two separate threads but still bridge one v8 context to the other has proved to be extremely difficult. As you have noticed the number of open issues on appjs has risen and the forward development of the platform has slowed while this issue has been tackled. Unfortunately as it stands today it has not been possible to move to a two thread/process solution and get a working internal bridge between the two v8 contexts.

I have discussed appjs with the head developer Morteza Milani. Due to the technical limitations of the current appjs technology appjs as it is today won't be getting new updates. He has begun pointing people to use node-webkit as an alternative to appjs and several developers have moved over to that project.

A New Direction:
============
I think that we mostly attract web programmers to the appjs project. It is mostly web developers that need or want to develop a desktop app using web technologies that get involved. There are fewer hardcore C++ programmers among us and that means the burden of development falls very heavily on a few shoulders.

My proposal is to get all of those javascript developers hacking on the appjs platform itself. To do that lets dial back the C++ and try to get as far as we can with javascript and web technologies. Where we hit something we cannot get around we can build something in C++ and expose it as an api to call from javascript. If we find an alternative using javascript lets provide that as well so the platform is more hackable to the largest number of people. The one exception to this rule is nodejs native C++ modules, I think we can just use them if available or provide a choice between C++ module and an equivalent javascript module.

Maybe you are thinking that this will mean that we will only be able to have a very limited and essentially crippled platform. However the more that I have thought about this approach and the limitations the more I think it is going to be capable of. Since nodejs has native C++ modules that are available to javascript and an amazing number of npm modules available this is not the limited platform you would at first think.


Concreate Plan:
============
This new direction can succeed if developers get excited and have some fun trying to take this idea as far as possible. This is an open source project so we can all benefit from each others solutions and experiments.

What I am proposing is that we have an "off-the-shelf" standard chromium binary on the disk. We also have a nodejs binary on the disk. Nodejs starts and boots off chromium and we have then solved the nodejs blocks chromium and chromium blocks nodejs problem we got stuck on. We also magically get all of the latest web technologies in chromium "for free" and if you want some new cutting edge technology get hold of the latest chromium binary that provides that functionality, drop that into the folder and take advantage of the functionality straight away. Likewise want to use nodejs 0.10 then just drop that binary in, no compilation issues, no compatibility issues.

With this new design we just got lots of things for free we could not have easily before. However we have also lost something major: we lost the internal bridge between the two v8 contexts and we lost the cross platform native desktop integration.

Lets start from the new design of having two binaries and then lets work through and develop solutions to connecting the nodejs backend to the browser frontend, and try to make the end solution as close to a native application as possible.

I am going to be using this setup to build a number of desktop applications for my own use. If we all start working in this direction then I am sure we can actually come a long way.

Short Discussion:
=============
I just want to answer some obvious questions people may ask about the new approach.
1) Communication:- nodejs opens a websocket, chromium is given the page to load and display on startup and this opens a websocket back to nodejs. Now you have two way communication and can pass json messages between the contexts. Chromium also reads its files from nodejs as normal http communication.
2) Packaging:- I have previously developed code that lets you take your "site" i.e. the browser stuff and the nodejs stuff and wrap it all up into a single package file. You can then have a single install of the nodejs and chromium binary that can run the package files.
3) Run code from node in chromium:- just take your function as a text string and send it to chromium, it can then eval the code.
4) Access DOM from node:- Use the remote debugging protocol. https://www.webkit.org/blog/1875/announcing-remote-debugging-protocol-v1-0/ It is possible to remotely connect to a running webkit and then manipulate the dom, change it, iterate over items and everything that you can do in firebug or webkit inspector. The only problem here is security. Hopefully it would be possible to make chromium only allow remote debugging from nodejs. If you search the web you can see people have created remote interfaces that can debug javascript on the fly and evaluate commands as you type them in. So actually this would give us something like the original appjs bridge. http://jsconsole.com/remote-debugging.html. Protocol is json format so perfect for a web developer to hack with.
5) Native functionality: On linux connect into DBUS, there are already npm modules that can be used. Create a javascript shim that provides an API and then uses dbus to communicate with the system. On windows you can open a powershell process and then pipe commands to it and have access to all of the .NET objects in windows. Create a javascript shim / api and then other platforms can implement the same or similar api so desktop app runs cross platform.
6) Desktop Drag and Drop: create a native executable that opens a small window with a "drop here" icon, when the drop occurs do a POST to nodejs with the filenames of the files and folders that were dropped.
7) Private Port:- Chromium app can have a client certificate, nodejs can refuse to talk to anyone connecting to the socket without the client certificate (problem with this is someone can just copy the client certificate from the chromium folder, anyone have a solution?).
8) Cross platform:- lets run on mac / linux / windows as we do today, allow native integration to the desktop and special platform functionality through api's so the desktop applications can be as good as possible.

Basically when you think about it we can work around many problems and get a lot of functionality for this platform. If we get a lot of contributions then the platform can develop quickly and I believe be very useful as a rapid desktop application platform.

Call for Help:
=========
We can all sit and hack our own desktop applications but it is even more fun to do it together. It is also a great way to learn and develop as a programmer. If you are a professional developer you will find open source programming is different to commercial programming and can be fun to do as a hobby.

If you would like to be able to rapidly build desktop applications using web technologies then this is the project for you. There are literally hundreds of different technologies that we could use to reach that goal. There are chrome packaged apps, phonegap, node modules and future technologies and api's that have not been thought of yet! Think what your future apps would need and then begin coding and hacking some form of solution. Show it off to everyone else and inspire them to hack something even better. Create a little pull request and get your changes into the project and mention you are an open source committer in your next job interview!

Today I am not presenting any new code since I want to hear what everyone has to say first and hear what ideas you all have for future appjs direction. That feedback can then affect and steer how we build the first prototype. Having said that it is quite easy and would only take a couple of hours to have a nodejs binary, chromium binary and websockets code talking together to be the first implementation. Then from that we can experiment and add a lot of functionality as developers need it for the projects they are developing. I can contribute a packaging solution and others can improve on it.

There are many awesome developers that have contributed and used appjs in the past and you are very welcome to start hacking on appjs itself. We would really like to encourage more contributions from everyone.

Maybe you have never contributed to an open source project before or used github or know what a pull request is. No problem everyone has to learn at some time, it is much easier than you would expect!

I know there are many companies and consultancies that are using appjs. This is a great opportunity for you. You can contribute code and move the platform so that it meets your needs while benefiting from everyone elses contributions and testing of the code in daily use. If we had 3 or 4 developers with some time on their hands we would get a lot done.

It kind of goes without saying but this is open source so no matter how clever you are, or how amazing the idea, demo code wins over theory every time so if you have a great idea then get your keyboard out and put together a very bad first demo of the concept and then take it from there. Code always beats nice theoretical ideas!

The only thing that beats code is of course documentation, tutorials, example code and demo apps. This is so important since this is how we all learn about the platform. If you want to make appjs accessible to others then that is amazing and very important.

I will finish by saying that there is a lot of room for new people so if you have time to contribute then you are more than welcome to the team. Also since I have not yet presented any code you can get a head start on me and hack something together yourself along these lines over the weekend and then show it off to us all ;-) I have said that demo code beats ideas and theory so go for it and your code could be the first prototype!

/Simon

Kevin Ingwersen

unread,
Sep 6, 2013, 2:40:19 AM9/6/13
to appj...@googlegroups.com
Hey there pal.

Amazing words you've written there and I took my time and read it whole.

I agree that appJS is an amazing product, and I personally wouldnt have been able to develop drag0n. It now is in heavy development and has the possibility of defining new PHP standards - as thru a module it just learned multithreading.

I sadly can not code c++ - but i am an enthusiastic hacker :) As you can tell, the fake-CGI environment, that now enables me a full-fledged PHP environment in appJS is sort of a big hack - at least to me. And because I was able to control the "new environment" for the spawned process, I was also able to slightly append some hacks that enabled me to create a fully self-contained package. I dont have any outside-dependencies anymore.

However you are going to make the future of appJS, I will try and get the ahx coming in. Especially I will keep trying to stick to my PHP, because I simply feel at home there x). But not just that, I might actualy develop a piece of javascript that will allow a fake-bridge; such as an API that sends informations to nodejs, and returns the output just like it WAS nodeJS. But under the hood, it will use the remote debugging, or socket. Because, socket, was quite a keyword. Thru a sucket, we can send informations from one process to another. So we could send a JSON object with: {"var":"process.env"} or {"call":"child_process.spawn","args":[1,2,3]} and have nodejs send another object back with the relevant return values. A pseudo-bridge, just as I said.

So once I am able to get my hands on there, I will try and get this approach done with alternative methods to C/C++.

As you speak about open source; I have just recently pushed my current appJS package to github. It runs out of the box on a Mac and had impressed another few people quite a lot. So, I was giving in my theory once, but now I brought the code that should demonstrate why i did not want to use node-webkit. For one, it is more or less "just a browser".

I hope to see an example soon, so I can hack together the JS bridge =)

Kind regards, and happy coding,
Ingwie!
--
You received this message because you are subscribed to the Google Groups "appjs-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to appjs-dev+...@googlegroups.com.
To post to this group, send email to appj...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Simon Horton

unread,
Sep 6, 2013, 3:04:03 AM9/6/13
to appj...@googlegroups.com
Hey Pal,

Yes doesn't moving to websockets and a browser binary open up a lot of possibilities? There are challenges but I am willing to try and code my way around them.

We create some kind of minimal start api to send json messages between the two processes. Then since it is open everyone can pile on and add in what they need to have.

Since we would be using websockets and php is also very easy to distribute as a binary you could actually just get php talking directly to that websocket. That way we would have two language implementations of the protocol and that can improve the quality of the implementation a lot. It would not be a hack but would just be a different backend. The same could be done with python or anything else.

Basically the websocket to a nodejs / php or whatever backend is being used to bust out of the sandbox of the browser to provide desktop application like functionality.

Simon 

Kevin Ingwersen

unread,
Sep 6, 2013, 3:30:16 AM9/6/13
to appj...@googlegroups.com
Hey.

Okay, I know websockets - but, I need to learn how to use them. Well that'll require me to rework my current drag0n build a lot x)
But, I will get there, and then we have another good example package of an actual desktop app. I am currently developing the core itself; the installer class.

Let me - or us as the comunity - know of any prototype or update.

Regards, Ingwie

Simon Horton

unread,
Sep 6, 2013, 3:46:34 AM9/6/13
to appj...@googlegroups.com
Well for dragOn the cgi connection to php would still work so it would not require any rewrite.

I will let everyone know about the prototype, you have done so many things with dragOn so it will be great to have you hacking on the prototype as well :-)

/Simon

Kevin Ingwersen

unread,
Sep 6, 2013, 3:52:05 AM9/6/13
to appj...@googlegroups.com
Well of course I will be hacking with the prototype! Pass me that ASAP, and I will be going thru and against it untill I managed that.
I actualy need to modify the CGI environment so that my self-contained libraries are loaded properly. Let's see how that is gonna end =)
Also, thanks for the compliment on drag0n ^.^ (its a zero, not an O, just sayin' ^^; )

Simon Horton

unread,
Sep 6, 2013, 3:55:43 AM9/6/13
to appj...@googlegroups.com
yes sorry I noticed that and updated the wiki page to be drag0n not dragOn!

Ægir Örn Símonarson

unread,
Sep 6, 2013, 6:19:40 PM9/6/13
to appj...@googlegroups.com
Simon,

Have you considered making the chromium binary web framework agnostic. That would allow developers from Rails, Django and other to use this that binary to build desktop applications with the server side framework the currently know. This could be benifical fro developers needing a desktop application that needs to share some code from a web app. 

At least i have often wanted to have a desktop shell to wrap around a rails + Ember.js projects.

Kevin Ingwersen

unread,
Sep 6, 2013, 6:30:42 PM9/6/13
to appj...@googlegroups.com
Hey.

I dont know what you ment with "agnostic" - but once I get my hands on the prototype of this, I will be coding a PHP interface. Porting that method to anything else - shall it be Rails or Django - shouldn't be that hard. :)
So just wait...I am just waiting too to poke the new "version" with all my fingers ^-^

Regards Ingwie

Ægir Örn Símonarson

unread,
Sep 6, 2013, 6:47:23 PM9/6/13
to appj...@googlegroups.com
English is not my native language so this might not be the correct word, but I think you got the point.
I'll be looking forward to see how you implement this and to use that with a Rails app.

Kveðja,
Ægir Örn Símonarson

Hugbúnaðarsérfræðingur.

Sími: 822-3325

Kevin Ingwersen

unread,
Sep 6, 2013, 6:58:50 PM9/6/13
to appj...@googlegroups.com
Dont you worry - english is not my native language too. Im a Deutscher. So - appJS is quite internationaly used x)

Simon Horton

unread,
Sep 6, 2013, 8:25:03 PM9/6/13
to appj...@googlegroups.com

Hi Ægir,

Yes great point. I think there are lots of developers who can do so much so quickly on the web. Then for whatever reason we want to create a desktop application. That takes forever and the interface is not as good as what we can do on the web. As you mentioned we want easy / natural communication to the server.

I think calling it a "desktop shell" that you wrap around a server side application is a very good way of describing what I want to build.

You have got me thinking how do we build this so it is easy and natural to take a php / Rails / Djano / etc app and deploy to the desktop. Appjs did that for nodejs and Ingwie managed to use it with php. We should make it easy to do with any framework.

Great comment, I think this should be a goal of the project.

I always liked that appjs ran on mac / windows / linux as well. So whatever we do lets make it work on those platforms.

I built a cgi interface for appjs, and using websockets and an api is also available. Any suggestions about how to make a nice pluggable system that can be used with many backends?

Simon

--

Simon Horton

unread,
Sep 6, 2013, 8:32:14 PM9/6/13
to appj...@googlegroups.com

Hey Ingwie,

This is great I see you are ready to get hacking already :-) Even really big projects only have 3 or 4 developers hacking the core so if a few of us come together and build what we ourselves need then we will go far.

I think your experience of using php with appjs is very good for us. We should try to remove as many difficulties as possible and make it easy to get your app onto the desktop.

Simon

Kevin Ingwersen

unread,
Sep 6, 2013, 8:45:08 PM9/6/13
to appj...@googlegroups.com
Hey Simon.

Oh yeah, I have been a loner in coding forever and I know the difficulties of "hacking" something - or as I always kept saying in my chat that I run: Trying to kick soemthing untill it fits is nothing but constantly breaking your feet - over, and over, and over. But at some point, you hit it totally right and it'll snap in its place and work, and you'll be wondering for what oyu paid all the hospital bills. XD

In other words; I love trying to get something to work. And that is why I actually would like to know a little bit more about how you plan to let the new appJS "look" like. I have made concepts of appIO, the "pseudo-bridge" of the contexts. I also have seen approaches in using websockets in PHP - so I will probably port the appIO interface to both - javascript and PHP, depending on how the new design is going to be like.

AFAIK it will be based on websockets...which means we have a duplex connection between the one and the other process. But, what else is there to know? I am no C/C++ dude, but i definitively am somebody willing to engage into appJS and help out on it =)

Just see drag0n as a big playground I had over all the years and which is where I developed my skills. So technically, everything I know will be in there...including all my hackology =)

So, lemme know a little more about the new concept/design, and I will see what I can do to help you and @milani to evolve appJS into a language-friendly app...at least, as far as I can ^^;

Regards, Ingwie

Simon Horton

unread,
Sep 6, 2013, 9:03:59 PM9/6/13
to appj...@googlegroups.com

At the moment the concept / design is real simple - it will obviously get more complex in the future. However there are hundreds of ways to build this thing. I dont want to come with a single way and lock out all other solutions. Instead I want to open it up and we can all have fun and build off each others ideas.

Let me describe the task like this:

1) we have something we know how to do well - php app for you, rails for someone else, nodejs for others. That lets you build applications and in one way or another provide an html interface for the user.

2) We can have our "own" browser, either chromium or cef or firefox or whatever. But we want it presented as a desktop app. Launch it from the dock or start menu.

So to start with we could just boot off the browser with parameters to remove the bookmarks bar etc and point it at the local "server side" app. Add api to allow communication both ways and you already hqve a very useful solution. Compaired to current appjs we loose the native menus and a couple of other things. But I think we can start basic and then try to hack solutions to the limitations and make the end desktop solution better and better.

All of that could be done without any C++ and no build process - and I think it will mean more developers that are perhaps afraid of C++ hacking would then jump in and be prepared to contribute.

Dont misunderstand me though, I have nothing against C++ at all I am just aiming to make the core more accessible to a larger audience. This is an experiment. I am saying ok how far can we get with C++. Then we can see what we can build. Then appjs 2.0 will be a mixture of appjs that we have now and the cool things from this experiment.

Having said that I fully expect to be able to ship apps to internal users (I.e. users in the same company) using this experimental technology so I believe it will be fully featured.

Simon

Simon Horton

unread,
Sep 6, 2013, 9:11:55 PM9/6/13
to appj...@googlegroups.com

Sorry correction needed: how far can we get WITHOUT C++.

Typing this on a mobile phone so many mistakes :-)

Kevin Ingwersen

unread,
Sep 6, 2013, 9:39:17 PM9/6/13
to appj...@googlegroups.com
Ahh...now that gives me an idea.

What we'd need is a customized, little browser. Stripping all of the - for "us" - nonsensual stuff such as bookmarks and alike should give us a window. But the browser also needs to be able to be called with a parameter to open up a specific website - our app.

Using a socket-like connection - websockets seem like they could work - we could pass things between the browser and its backend.

That logic, is quite simple.

Now, let's strip the backend and focus on the browser. What appJS could do, is, be JUST the browser. In that case, a webView that exports native code (i know it is possible) to the javascript scope. That way, we can add more native stuff. The backend from hwere is totally indepenent. But how is it parsed now? Solution: Miniature servers. PHP brings its own "debug server" with itself, which is just good enough to be used as a local webserver, which even saves some extra processes.
Another possibility is to enable configuration flags to the browser binary. Here are a few concept-examples:

./browser --protocol=ws --location=localhost --port=9090
./browser --protocol=http --location=$(dirname $0)/../web

Now, that should be quite self-explaining. From PHP, I can easily boot off a process like that and just break over the PHP script itself and exit that, and head into the browser window. What appIO in my concept will then be able to do is, execute functions and the like on backend. Since the backend is now completely unknown to appJS, it wouldnt have to worry about what it is dealing with, but rather be a nice servant and work out the protocol. In that case, we can simply add little defaults - like for the ws (websocket) protocol - so that we automaticaly can parse things. Thru websockets, we now can pass different things, such as events, states, and more. With the http protocol, we can query a http:// or file:// scheme on the local drive for data. I personaly would stick to websocket myself - but for a rather  basic app that relies more on javascript than the backend, http should do it just nicely.

So what I am saying is, you may simply offer a real great browser, and give developers the ability to create their own bootstrap code. Let's use the above said example for the ws protocol, and let me show you some conceptual PHP code for my personal case:

<?php
// Define some variables:
$WebRoot = dirname(__FILE__)."/..";
include "$WebRoot/php-bin/ws.php";
include "$WebRoot/php-bin/appIO.php";

class Server extends Thread {
public function run() {
( new \WebSocket\Server(...) )->run();
}
}
class Client extends Thread {
public function run() {
system("./browser --protocol=ws --location=localhost --port=6666");
}
}

// Start two threads - first the server, then the client.
// I use threads, because I have the module for it installed :)
// However, you could also just kick off two daemons - pseudo-multithreading...or fork. There are enough options.
// And there is one option for every language, i am so sure :3
if(! (new Server)->run() && (new Client)->run() ) exit -1;
?>

And thats it. I would here kick off a server and a browser. And in the browser, I can now use appIO to communicate back to the backend and execute everythign I want. Actualy, I could even spawn a nodeJS process and establish another websocket to it too.

Now, there is one BIG problem.

Everything sounds very great...but, appIO will not know all your backend's language. So what appJS needs is to extend V8 by some methods, that make it possible to create new events, such as the well discussed __noSuchMethod__, so that we can have appIO be dynamic. Now that way, a browser would be able to execute basic functions at the backend. The backend of appIO is just sending a specific formated JSON to the backend - and since it loaded appIO, it will understand what to do. Example:

var hname = appIO.system("hostname");
var php_version = appIO.getversion();

Thats super basic, I know...but should do basic things at least!

One last thing - environment. Now here comes the joy. We have two processes, if one or another way, we'll have two. period :). To sync the environment, we can eighter use appIO as a bridge, a .pid and .env file parsable by both sides in a temporary folder that is made familar to the browser...or we just add parameters to the browser-binary. Because, since my own PHP is self-contained, I have to patch the environment with variables to tell the dynamic linker to look at different places for the libraries. That is quite rare for other appJS apps, but, something to consider for self-contained and rather big ones. Because a shared environment allows something else: cooperation. Let's say we realize that the client is suddenly offline - from the real internet - and we need to tell our backend. Well, we can do that very easily over environmental variables: APPJS_C_ONLINE=no

As yo can see, I sat here and thought about that all for a while. And this is just my personal input. :)

Hope it helps!

Kind regards, Ingwie!
PS: I need another bottle of cola...care to donate one? XD

Simon Horton

unread,
Sep 6, 2013, 9:50:41 PM9/6/13
to appj...@googlegroups.com

Great you have understood my concept.

I think there are hundreds of ways of connecting the backend to "desktop shell" and making the "desktop shell" as close to a native desktop application as possible. The shell is just a browser of some form that we run.

Lets experiment and build a load of prototypes, then cherry pick the best ideas and put them in appjs 2.0

I think communication via json is very widely supported likewise html so we have all of the basic ingredients already.

Simon

Kevin Ingwersen

unread,
Sep 6, 2013, 9:55:08 PM9/6/13
to appj...@googlegroups.com
I'll definitively go over all the prototypes and test them out. :)
Hope to see such prototype soon, because I am that curios! ^.^

Kevin Ingwersen

unread,
Sep 6, 2013, 9:58:19 PM9/6/13
to appj...@googlegroups.com
Also, once I get to test and to start making some progress on appIO, i'll start pushing it to github...as said, I can only make a JS and PHP version. Others probably can port it to other languages, like python 'n stuffs. Hope you like the concept of it though! ^^
Am 07.09.2013 um 03:50 schrieb Simon Horton <siho...@gmail.com>:

Simon Horton

unread,
Sep 6, 2013, 10:04:16 PM9/6/13
to appj...@googlegroups.com

Ingwie - you have already understood my concept and know how you would implement the php side. I will put together a basic prototype using just a download of nodejs and chrome. Then you can take that and play with it adding in support that you would like to see. Will be amazing to see what you can do with it.

Would be nice to hear what others would like to see, what functionality they need and if they have any suggestions on architecture or implementation.

Simon

Kevin Ingwersen

unread,
Sep 6, 2013, 10:15:09 PM9/6/13
to appj...@googlegroups.com
Sounds about right! :) Will be waiting right here ^.^

Chris Banford [Webascent]

unread,
Sep 7, 2013, 4:59:04 AM9/7/13
to appj...@googlegroups.com
Hi guys,

Just wanted to pipe in with a good portion of encouragement!

I've been following AppJS for quite a while and was hoping that it would mature to the point where I would have been able to use it to build some simple developer tools for myself (simple web UI + SSH + Portable between OSs!). Sadly, it seemed to fizzle and the only other option appears to be node-webkit (which I also follow & play with).

Am also not a C++ guy, but enjoy building things in many other languages. I've got strong graphics skills and seeing the current energy between Simon & Kevin, would be willing to pitch in a bit of time where it would help most.

My first suggestion to you two would be to come up with a skunkworks type code name for this (new) project, to make discussing it easier. AppJS would then be its ancestor and the distinction between the two would be clear to all. As things move forward into a proper release, a thought-through final name can be decided upon.

Here's a couple of early morning, before the coffee kicks in ideas, to get things rolling:
  • DeskShell
  • AppShell
  • DeskBox
  • AppBox
  • v8App
  • v8Works
Love the energy of these mails! Hoping you guys find a sweet spot and manage to get this boulder rolling. :-)

Cheers,
-Chris



Simon Horton

unread,
Sep 7, 2013, 5:16:41 AM9/7/13
to appj...@googlegroups.com

Hi Chris,

Would be great to have your strong graphics skills :-)

Ok I think "DeskShell" can be the name of this experiment. It communicates my ideas of what we are building quite well.

Your developer tools sound interesting. Am I guessing correctly to understand a desktop app for changing a config file or similar but that reads / saves the result to a server over ssh?

Do you have suggestions for a 64x64 icon for DeskShell skunkworks project?

Simon

...

Chris Banford [Webascent]

unread,
Sep 7, 2013, 6:02:33 AM9/7/13
to appj...@googlegroups.com
Hi Simon - happy my thoughts have hit a nerve!

I'm buried in work (client meeting in about 20 min) right now, but will try and get a bit of brain-storming time in later today for some quick logo ideas.

Cheers,
-Chris


--

Simon Horton

unread,
Sep 7, 2013, 6:04:01 AM9/7/13
to appj...@googlegroups.com

Cool, take your time and have fun with it, no pressure.

Simon

...

Chris Banford [Webascent]

unread,
Sep 7, 2013, 6:19:37 AM9/7/13
to appj...@googlegroups.com
Absolutely! Will be fun :-)
-Chris

--

sihorton

unread,
Sep 7, 2013, 8:27:12 AM9/7/13
to appj...@googlegroups.com
For anyone who cannot wait to get hacking look at the following page:-


It lists all of the command line switches that can be used when starting chromium (the open source version of chrome). This page tells you how to use them: http://www.chromium.org/developers/how-tos/run-chromium-with-flags. I found lots of interesting switches that we can play around with:-

switchcomment
--appSpecifies that the associated value should be launched in "application" mode.
--app-idSpecifies that the extension-app with the specified id should be launched according to its configuration.
--app-window-sizeSpecifies the initial size for application windows launched with --app. --app-window-size=w,h
--apps-use-native-frameExperimental native frame support for packaged apps.
--desktop
--kiosk
--load-and-launch-app"Loads an app from the specified directory and launches it"
--no-startup-window"Does not automatically open a browser window on startup (used when launching Chrome for the purpose of hosting background apps)."
--profile-directory
--proxy-server"Uses a specified proxy server, overrides system settings. This switch only affects HTTP and HTTPS requests."
--remote-debugging-portEnables remote debug over HTTP on the specified port.
--unlimited-storageOverrides per-origin quota settings to unlimited storage for any apps/origins. This should be used only for testing purpose.
--user-agentA string used to override the default user agent with a custom one.
--user-data-dirSpecifies the user data directory, which is where the browser will look for all of its state.
--window-sizeSpecify the initial window size: --window-size=w,h
--window-positionSpecify the initial window position: --window-position=x,y

So from those it looks like we could create our own packaged app and launch that (it then can contact the websocket), we could run own own proxy server and communication with the browser like that. There is app, desktop and kiosk mode to play around with. All of that is available by just passing command line arguments to chromium when we boot it off.

I am sure that will trigger ideas in developers heads!

/Simon


Chris Banford [Webascent]

unread,
Sep 7, 2013, 9:07:03 AM9/7/13
to appj...@googlegroups.com
Hi Simon,

Not having a clue about the details, I'm curious if there's a possible way/path to offer native widgets this way?

-Chris


Simon Horton

unread,
Sep 7, 2013, 9:14:35 AM9/7/13
to appj...@googlegroups.com

I believe that yes we would be able:

a) native file picker: press button on webpage, this sends an event to nodejs over websocket, nodejs calls a C++ npm module that pops up the native file picker. Results of the pick sent back over websocket.
b) nodejs can boot off powershell and interact with it creating .net objects that popup file dialog
c) can create a windows exe from visal basic, nodejs starts that with parameters to open the file picker.

So my approach would be to create a library or module that supplies the native functionality then just call that from nodejs. Can have same api but different implementations for each platform.

Simon

Simon Horton

unread,
Sep 7, 2013, 9:21:04 AM9/7/13
to appj...@googlegroups.com

I guess my approach is to make the core so simple everyone can hack it.
Look in the mailing list how difficult it currently is to checkout and build appjs (admittably most of the difficulties are on windows). See aoso how many people respond and help with c++ issues.

By just booting off the browser everyone could hack the core, so the project will progress faster. The native functionality can be wrapped and supplied behind api's.

We wont be able to get to 100% native, but the more I have thought it through the more I think we can work around and solve the limitations.

Anyway it is an experiment to see how far we can go.

Simon

Chris Banford [Webascent]

unread,
Sep 7, 2013, 10:08:00 AM9/7/13
to appj...@googlegroups.com
Sounds like the correct approach to me. Keep it as simple (to develop with & develop for) as possible. The crowd that is interested in this is above all else looking for simplicity in creating desktop apps. You're right in not worrying about too many of the other details yet.

-Chris


Simon Horton

unread,
Sep 7, 2013, 10:11:03 AM9/7/13
to appj...@googlegroups.com

Yes you got my meaning. After you start thinking in this way then the concrete things you thought you could not do are actually possible in one way or another.

Simon

Kevin Ingwersen

unread,
Sep 7, 2013, 12:32:07 PM9/7/13
to appj...@googlegroups.com
Ooooooooo - looki looki! ^_^
I can totally start off with experimenting with that =). Which is what I will be doing...today. I'll just have food, kick back on a sofa and just start trying out what I can get. This also is what I needed to test appIO. Well, let's go and have some h4x0ring! (wat - Mac doesnt underline that last word as a typo? :D)

Simon Horton

unread,
Sep 7, 2013, 12:44:33 PM9/7/13
to appj...@googlegroups.com
Thought that you would be onto that quickly ;-)

Kevin Ingwersen

unread,
Sep 7, 2013, 2:53:37 PM9/7/13
to appj...@googlegroups.com
Well of course I'd get onto that really fast. But...woooooooow....2GB of source code?! Google simply wants to ruin my night it seems XD (or I oversaw something that was smaller...). Anyway. I'll let you know when I get to something.

Simon Horton

unread,
Sep 7, 2013, 2:56:54 PM9/7/13
to appj...@googlegroups.com
Try to find a pre-build binary for your platform and just use that, we can try using chromium without any changes to start with.

Kevin Ingwersen

unread,
Sep 7, 2013, 3:02:14 PM9/7/13
to appj...@googlegroups.com
I saw some builds, but they all had different "names" - like they added some name to it that made me think that the build was modified. So I am getting the plain version, build it myself, and can make sure I am playing with the real-deal :)

Simon Horton

unread,
Sep 7, 2013, 3:05:33 PM9/7/13
to appj...@googlegroups.com
Sure go for it.

Simon Horton

unread,
Sep 7, 2013, 3:17:16 PM9/7/13
to appj...@googlegroups.com
Found a site with downloads of chromium if anyone needs it:


Simon

Kevin Ingwersen

unread,
Sep 7, 2013, 3:22:34 PM9/7/13
to appj...@googlegroups.com
This looks legit to me. :)

Kevin Ingwersen

unread,
Sep 7, 2013, 3:26:19 PM9/7/13
to appj...@googlegroups.com
Ah, well, the freeSMUG build is exactly what I was avoiding x). I'll see if I can somehow break it off. I personaly dont want users to update something outside of my control o-o
Am 07.09.2013 um 21:17 schrieb Simon Horton <siho...@gmail.com>:

Simon Horton

unread,
Sep 7, 2013, 3:28:50 PM9/7/13
to appj...@googlegroups.com
Yes I agree, it is important that we get hold of a browser and deploy our apps then we don't want it to update by itself. It is only used to run our application not surf the wild web so it does not need to auto-update. But as a start we can use it before learning how to turn that off.

/Simon

Kevin Ingwersen

unread,
Sep 7, 2013, 3:34:05 PM9/7/13
to appj...@googlegroups.com
Yep, the freeSMUG build absolutely won't work without Sparkle (the update-framework):

dyld: Library not loaded: @loader_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle
  Referenced from: /Users/Ingwie/Work/google/Chromium.app/Contents/MacOS/Chromium
  Reason: image not found
Trace/BPT trap: 5

I have a tool to fix such things - but honestly, nope. I am going to wait untill my download is done. Ill post my compile once it is done, so those that want it for Mac can grab it.

Simon Horton

unread,
Sep 7, 2013, 3:42:11 PM9/7/13
to appj...@googlegroups.com
I have created a bintray package "appjs-deskshell" we can use for the distributables: https://bintray.com/appjs/appjs/appjs-deskshell

If you send me your bintray username I can add you as a member of the appjs group. Then you will be able to upload the mac chromium build that you create there :-)

/Simon

Morteza Milani

unread,
Sep 7, 2013, 3:42:40 PM9/7/13
to appj...@googlegroups.com
Hi everybody,

Thank you Simon for this proposal and others for their kind support specially Kevin.
As Simon said, I was working hard on the new appjs until problems happened one
after another in life and code. The result is that new appjs never published because
of only a big problem: I couldn't build the bridge between different processes.

Simon discussed with me a new solution, to use webkit debugger API to build the
bridge and I was amazed! I think it is the solution we need. Before anything else
we need to implement an experimental version of webkit debugger api in nodejs that
can handle DOM right inside node process and run JS from node to browser and back.

There is no C++ in doing that so js ninjas can help a lot!

Kevin Ingwersen

unread,
Sep 7, 2013, 3:51:09 PM9/7/13
to appj...@googlegroups.com
I am glad to hear from you again pal =)!
Well I love the idea too! We'll need to try different approaches, and see which works the best.
But...'amma be honest, I dont know the WebKit Debug API. o-o

Morteza Milani

unread,
Sep 7, 2013, 3:55:25 PM9/7/13
to appj...@googlegroups.com
You can always learn by reading the spec! It is just a protocol built with json messages! Send a json message it will do something! that's it!

Simon Horton

unread,
Sep 7, 2013, 3:59:11 PM9/7/13
to appj...@googlegroups.com

Kevin Ingwersen

unread,
Sep 7, 2013, 4:02:12 PM9/7/13
to appj...@googlegroups.com
Ohhhh xD! Well that is what i was basically planning to do with appIO. when we had two processes - browser and backend - they would communicate via standarized json messages and other cool stuff. (such as accessing functions exported by the backend from a JS scope). Ill read the link Simon posted and get to educate myself some more :3. The download has completed, Ill let it build as I read xD

Simon Horton

unread,
Sep 7, 2013, 4:04:40 PM9/7/13
to appj...@googlegroups.com
As an example code to make the page navigate to a new url is just to send a json message as follows:-

Page.navigate

request: {
"id": <number>,
"method": "Page.navigate",
"params": {
  "url": <string> 
}
}
response: {
"id": <number>,
"error": <object>
}

Navigates current page to the given URL.

All we need to do is to implement an api that then sends and receives these json messages, we can then use that instead of the bridge we had before.

If anyone wants to give it a go and see if they can get a little demo working then go for it!

I have created a blank github project you can fork and code inside if you want: https://github.com/sihorton/appjs-deskshell

/Simon

Kevin Ingwersen

unread,
Sep 7, 2013, 4:12:36 PM9/7/13
to appj...@googlegroups.com
That is fairly easy. But where do you send these things? Otherwise it would only be like:

var appIO = {
page: {
navigate: function(url) {}
}
}

That is actualy the only thing I didnt find - where to send these JSON messages?

Simon Horton

unread,
Sep 7, 2013, 4:15:37 PM9/7/13
to appj...@googlegroups.com
If I understand correctly (and I can be wrong) it is extremely easy, when you start chrome:-

--remote-debugging-port 9000          Enables remote debug over HTTP

So just post that json to localhost:9000 and you send it to the browser!

/Simon

Simon Horton

unread,
Sep 7, 2013, 4:24:56 PM9/7/13
to appj...@googlegroups.com
I have been discussing with Morteza Milani and it is possible that we can use a new build of appjs that uses separate processes for nodejs and chromium. We would then be able to use the remote debugging protocol to communicate between the two -- i.e. to replace the previous bridge.

This would mean we have all of the menu's, window frame and everything we have now but we also solve the stopping issues that we have with the existing bridge code.

Keep tuned everyone is having great ideas here!

Kevin Ingwersen

unread,
Sep 7, 2013, 4:38:16 PM9/7/13
to appj...@googlegroups.com
Ahh, thats great! WEll that solution would work too and actualy makes it easier to port existing apps to appjs-deskshell. I'll help you guys and provide you an api ontop of the protocol with appIO, making things a little easier. :)

Chris Banford [Webascent]

unread,
Sep 7, 2013, 4:49:49 PM9/7/13
to appj...@googlegroups.com
Love the energy!

I'm thinking that in keeping with quick iterative rounds that we should just do something super simple for an initial logo/icon. Also if this ends up being more of a continuation of appjs, maybe we can just do a minor change of Milani's existing logo for the project? (sort of losing the 'js' bit as you're looking to support any back-end).

A quick hack to get the juices flowing:



(the little dot in the middle sort of reminds me of the *Shell Game*)

Looking forward to the v1.0 release this Monday (at the way you're going at it!).

Cheers,
-Chris



Simon Horton

unread,
Sep 7, 2013, 5:04:39 PM9/7/13
to appj...@googlegroups.com
Great thanks Chris! I have accepted your pull request and added the graphics directory :-)
ghjchajf.jpg

Kevin Ingwersen

unread,
Sep 7, 2013, 6:40:56 PM9/7/13
to appj...@googlegroups.com
Bad news from here.

So, I was having some time trying to download the source...turns out its WAY over 7GB. In the meantime, I googled "chromium github" and eventually found a github pge. But, I wasnt able to compile - because...err, how? o-o

Googling a little more gave me a chromium pre-build for mac - very bare and blank and off-the-trunk, just what I needed. I played with it and added/removed flags. I was indeed able to launch a chrome-packed webapp...but, I wasnt able to get rid of the browser. Whatever I tried, the browser window just kept popping in. I even understood a few of the flags:

--app and --desktop Force chromium into App or Desktop mode

So this took away a promising one. Others were just alike and didnt do a thing. :/

Taking another google-tour turns out, that we MUST use CEF. the key is the E:
Chromium Embedded Framework
I facepalmed when I thought about it - and here is why.

Chromium seems like a minimal Chrome browser with a few more switches, and has a lot of debugging flags that normal Chrome apeparently doesnt have. So, as a minimal browser, it is still a browser - and it won't change on that topic. The embedded framework however can be treatened and kicked into place where it may fit - its not a browser, but it's rather a "web-view".

So what I learned today is, that we - unless somebody finds a solution or a lightbulb randomly pops up over my head  - have to rely on CEF. x.x

Thats at least the status so far, I will try and see what I can figure out. Fingers crossed.

Regards, Ingwie
Am 07.09.2013 um 23:04 schrieb Simon Horton <siho...@gmail.com>:

Great thanks Chris! I have accepted your pull request and added the graphics directory :-)
On Sat, Sep 7, 2013 at 10:49 PM, Chris Banford [Webascent] <ch...@dihedrals.com> wrote:
Love the energy!

I'm thinking that in keeping with quick iterative rounds that we should just do something super simple for an initial logo/icon. Also if this ends up being more of a continuation of appjs, maybe we can just do a minor change of Milani's existing logo for the project? (sort of losing the 'js' bit as you're looking to support any back-end).

A quick hack to get the juices flowing:

<ghjchajf.jpg>

Kevin Ingwersen

unread,
Sep 7, 2013, 6:49:37 PM9/7/13
to appj...@googlegroups.com
Wait a moment.

chromium --app=URL

GODDAMNIT, dudes need to document flags rightful. This totally did what i wanted o-o...back2hack
Am 07.09.2013 um 23:04 schrieb Simon Horton <siho...@gmail.com>:

Great thanks Chris! I have accepted your pull request and added the graphics directory :-)
On Sat, Sep 7, 2013 at 10:49 PM, Chris Banford [Webascent] <ch...@dihedrals.com> wrote:
Love the energy!

I'm thinking that in keeping with quick iterative rounds that we should just do something super simple for an initial logo/icon. Also if this ends up being more of a continuation of appjs, maybe we can just do a minor change of Milani's existing logo for the project? (sort of losing the 'js' bit as you're looking to support any back-end).

A quick hack to get the juices flowing:

<ghjchajf.jpg>

Kevin Ingwersen

unread,
Sep 7, 2013, 7:21:03 PM9/7/13
to appj...@googlegroups.com
Looks like we can have the application show just our app and disable many other UI controls - but the menu will, sadly, stay. At least that's a good thing to start with. This should work with any chromium install:

1. create a web server in nodejs
2. spawn a process of chromium with the following spawn-call:
spawn("/path/to/chromium", ["--app=http://localhost:port", "--disable-translate", "--remote-debugging-port=6666"]) 
3. Prepair yourself a singleton with a .send method which performs a POST request to localhost:6666 with the WebKit Remote Debugger standart JSON message.
4. Try to communicate forth and back between the browser and the backend...that is basically what I am about to be doing now.

The thing is really the menus. The user still has a good amount of options to click and toy with. I didnt spot a way to limit that (...yet).
Am 07.09.2013 um 23:04 schrieb Simon Horton <siho...@gmail.com>:

Great thanks Chris! I have accepted your pull request and added the graphics directory :-)
On Sat, Sep 7, 2013 at 10:49 PM, Chris Banford [Webascent] <ch...@dihedrals.com> wrote:
Love the energy!

I'm thinking that in keeping with quick iterative rounds that we should just do something super simple for an initial logo/icon. Also if this ends up being more of a continuation of appjs, maybe we can just do a minor change of Milani's existing logo for the project? (sort of losing the 'js' bit as you're looking to support any back-end).

A quick hack to get the juices flowing:

<ghjchajf.jpg>

Kevin Ingwersen

unread,
Sep 7, 2013, 8:13:34 PM9/7/13
to appj...@googlegroups.com
So, there is no way getting the menus and such apart from the app. But for now we have something to try out. But it seems that the idea of re-trying the previous appjs concept with the change of spawning the browser into a different process is a good idea. Because, I can google as much as I want, there is no way of using some sort of standalone binary to spawn just a webview.

@milani: Think you can hack together a small programm with CEF3 that basically spawns a webview with the supplied URL? That'd be a start I think...and since you know CEF, that shouldnt be too hard...but, then again, im just guessing :)

Morteza Milani

unread,
Sep 8, 2013, 12:35:33 AM9/8/13
to appj...@googlegroups.com
Kevin,

If you guys implement the bridge on top of webkit debugging protocol, I will add it to appjs. It would have all features appjs currently has and a lot more. It will spawn processes, opens the debugger port and allows custom frames and menus. So don't worry about it, we just need to test and implement the full protocol to continue appjs like before.

Simon Horton

unread,
Sep 8, 2013, 3:15:13 AM9/8/13
to appj...@googlegroups.com
Hi All,

I have a working demo of using the remote debugging api for chrome. I was able to get the page to navigate to a new url! Here is a test file that you can run:-

/**
* Demo of using chrome remote debugging api.
*
* 0) npm install ws
* 1) Close all open chrome windows and launch with the following:
*   path/to/chrome --remote-debugging-port=9222 --user-data-dir=path/to/a/folder
* 3) find webSocketDebuggerUrl value (will look like ws://localhost....)
* 4) copy the url to the webSocketDebuggerUrl below
* 5) node rApi-demo.js
* 6) the chrome window should navigate to appjs.com!
*/

var webSocketDebuggerUrl = 'ws://localhost:9222/devtools/page/A4CB0085-8ACD-4E3C-BC53-0BA888EFC4D6';
var url = 'http://appjs.com/';

var WebSocket = require('ws');
var ws = new WebSocket(webSocketDebuggerUrl, {protocolVersion: 8, origin: 'http://localhost/'})
ws.on('message',function(mess) {
console.log('message:',mess);
});

ws.on('close',function() {
console.log('disconnected');
});

ws.on('open',function() {
console.log('connected');
ws.send('{"id":'+1+',"method": "Page.navigate","params": {"url": "'+url+'"}}');
});

We would just need to create an api to wrap the implementation, connect to the debug port on startup and then we should be able to control the browser.

/Simon

Simon Horton

unread,
Sep 8, 2013, 7:11:25 AM9/8/13
to appj...@googlegroups.com
I have now implemented a remote debugging api we can use in appjs in place of the existing bridge. I have implemented an initial set of functions and can implement more in the future:

npm-install chrome-rdebug

First you will need to close down chrome and then run it from the command line passing in --remote-debugging-port=9222 and on windows you will need --user-data-dir=path/to/a/folder.

To check that is working ok open "http://localhost:9222" in a browser. Next open "http://localhost:9222/json" and select one of the pages listed to debug, find the webSocketDebuggerUrl attribute and copy that. It will look something like: ws://localhost:9222/devtools/page/A4CB0085-8ACD-4E3C-BC53-0BA888EFC4D6.

The api uses the Q promises library to wrap the calls to the websocket so that you can easily program a sequence of events. I will show further examples of this in the future. The following code (demo1.js in the chrome-rdebug module) will connect to the running page, output the source html of the page and then make it navigate to appjs.com for 5 seconds and then navigate to about:blank

var rDebug = require('chrome-rdebug').rDebug;
var rDebugApi = rDebug.openSocket('ws://localhost:9222/devtools/page/A4CB0085-8ACD-4E3C-BC53-0BA888EFC4D6');
rDebugApi.ws.on('close',function() {
console.log('disconnected');
});
rDebugApi.ws.on('open',function() {
console.log('connected');

rDebugApi.getDoc().then(function(doc) {
rDebugApi.getOuterHTML(doc.root.nodeId)
.then(function(res) {
console.log("page html:",res.outerHTML);
rDebugApi.navigate2("http://appjs.com").then(function() {
setTimeout(function(){
rDebugApi.navigate2("about:blank")
},5000);
}).fail(function(err) {
console.log("error:"+err.error.code+" "+err.error.message);
});
}).fail(function(err) {
console.log("error:"+err.error.code+" "+err.error.message);
});
});
});

 Next on the todo list will be to automatically find the websocket address and connect to it, or provide an api to do the same.

/Simon

Kevin Ingwersen

unread,
Sep 8, 2013, 7:35:09 AM9/8/13
to appj...@googlegroups.com
And we both just created two different approaches - but in the end, we're doing totally the same =)
Love portability!

IngwiePhoenix

unread,
Sep 8, 2013, 7:41:32 AM9/8/13
to appj...@googlegroups.com
!! If this email appears twice, its because it didnt appear in google groups when I checked if it was there and am now responding with the original content from the groups page directly. !!

Ok, turns out my google'ing gave me some ideas.

When appJS implements the remote protocol, we do need an option to manually show the window - and that is important, like, a lot. Let me give you some PHP code so you see what I am talking about...code, as simon said, beats theory.

<?php

// Just love the new array syntax~
$ServerInfo = [
"port"=>9001, // our WK-RDP port
"host"=>"localhost",
];
class AJAX {
private $url;
public function __construct($host, $port) {
$this->url = "http://$host:$port";
}
public function post($values) {
return $this->perform([
'http' => [
         'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
         'method'  => 'POST',
         'content' => http_build_query($values),
     ]
]);
private function perform($http_values) {
if($context  = stream_context_create($http_values))
return file_get_contents($url, false, $context);
else
return null;
}
}
}
// This will be a new thread, so the browser does not blog us
class appJS extends Thread {
public $settings;
public function __construct($s) {
$this->settigs = $s;
}
public function run() {
/* Settings could look like this:
[
"useAlpha" => true,
"title" => "Hello World!",
"method" => "ws",
"server" => 9002 // <- This is the port appJS should contact PHP as it's backend!
]
This now means, appjs is supposed to send a message to PHP to request pages - giving in the URL.
ex: [
"request": "get",
"url": "/"
] */
$callStack = ["appjs"];
foreach($this->settings as $flag => $param) {
$callStack[] = "--".$flag.'="'.$param.'"';
}
// ['appjs', '--useAlpha="true"', ....]
system(join($callStack)); // aaand it runs.
}
}
class appIO extends WebSockets {
// This class inherits a very great websockets interface :)
public $ajax;
public function connected() {
$this->ajax=new AJAX;
echo "--> Connected.\n";
}
public function closed() {
$this->ajax=null;
echo "--> Closed.\n";
}
public function process($data) {
// Process data, such as the GET requests and such that we gonna get from the server.
}
}
class appIOThread extends Thread {
public $io;
public function run() {
$this->io = new appIO("localhost", 9002);
}
}
// Ok, all the preperations done.
// To summarize: 9001 is the port used for WK-RDP, to where we send commands, or more, our answers to...
// ...messages that came to our port 9002 on which we will be listening.
$app = new appJS([
"useAlpha"=>true,
"wk-rdp"=>9001,
"method"=>"ws",
"server"=>"localhost:9002",
]);
$io = new appIOThread;
if(! ($io->start() && $app->start()) ) exit 1;
// Both are threaded and ready. Let's tell appJS to show by sending the we-are-there message:
$io->send(["showWindow"=>true]);
/* What will happen now is perfectly simple:
1. PHP is now prepaired with methods and functions to handle requests/messages from appJS!
2. We first spawn a thread with our websockets server, which now listens on port 9002.
3. THEN we call the appjs browser binary with all the different args - and as soon as it pops up, it sends some message to PHP like:
{ "method":"get", "location":"/" }
4. PHP now resolves that requests and responds with the HTML output, pulled into another json object:
{ "location":"/", "content":$content }
5. AppJS now displays our page - cool! Now, from within there we have another appIO instance, in javascript, which now wants to execute some PHP function.
Like, it'd like to check the system's uname:
var uname = appIO.call("system", ["uname -a"]);
which results in:
return system("uname -a");
6. The output is sent back to the other appIO instance.
7. Lets say we have spawned another thread with a daemon to check for updates for the software. What now happens is, that we tell appJS to call a js function:
$appIO->call('$("#update-dialog").show();');
8. We post the fitting JSON object according to the WK-RDP standarts to appjs' opened 9001 port.
9. We process the message, and the JS is executed.
In another situation, we also could time things. Like, from the appjs end, we can tell PHP to start running something.
Then, it first does a "Page.navigateTo" request to appjs to show a nice "Processing action" page.
In the meantime, it actually processes the action, like checking dependencies for whatever action.
We send another "Page.navigateTo" to appjs to change the page again - completely automated!
But the cool thing here is, this is SUPER portable:
You just need a websockets server.
AppJS just needs to be told the port to send stuff to.
And thats it. :)
*/
?>

Again, just an extremely rough idea. PHP doesnt have native forking or multithreading, so I did indeed speak about my custom build which includes pthreads, so I can start things in threads. :)

Simon Horton

unread,
Sep 8, 2013, 9:30:51 AM9/8/13
to appj...@googlegroups.com
Hi Ingwie,

Yes that code looks right. Maybe if we are posting code we could use gists: https://gist.github.com/ you put the code there and then link to it and you get syntax highlighting etc.

So your code could boot off the browser / appjs and then open websocket connection and send stuff there and get stuff back. It is quite a nice design when you get used to it, and very easy to extend since you just add more methods to the api object.

Personally I prefer having this direct websocket idea and sending messages back and forward, but I have implemented the chrome-rdebug nodejs module for talking to the remote debug protocol. We can try both methods and see what works best.

Now we have the basic module done we can see if a new appjs binary can be compiled. If that succeeds (and it should since it was just the bridge code that was failing before) then we will have a prototype for you to checkout.

As I said before we can try a couple of different approaches and then pick the best things to include in the final version.

/Simon


--

Kevin Ingwersen

unread,
Sep 8, 2013, 10:01:39 AM9/8/13
to appj...@googlegroups.com
Well, we technically did the totally same thing. I need to write my own rDebug module for PHP anyway x). But it is basically the same, just another language, but the exact same result. ^.^
Now we just need the low-level stuff, @milani's work, to create an appjs binary that we can call to create the browser window, and make sure we get rdebug. ^^
This is going into a very awesome way, imho!

Simon Horton

unread,
Sep 8, 2013, 12:08:45 PM9/8/13
to appj...@googlegroups.com
Well I have just been watching a long documentary film and so thought I could add in the missing functions to the chrome-rdebug library. I now have full implementations for:-

  • Console
  • Page
  • Runtime
  • Timeline
I have implemented them according to the documentation, so you can use that to check for parameters documentation.

/Simon

Kevin Ingwersen

unread,
Sep 8, 2013, 12:42:39 PM9/8/13
to appj...@googlegroups.com
Awesome! I'll get my rDebug class for PHP started soon...just...gotta get out of my lazyness. ^^;
Well worked there man!

Simon Horton

unread,
Sep 8, 2013, 1:36:21 PM9/8/13
to appj...@googlegroups.com
I have now implemented the full Api for chrome remote debugging! I have also added an event handler implementation so you can register handlers to handle events. Having gone through the full api it does look like it is enough to build a good bridge with. We won't be able to access the document via jquery as it was before, but you can identify a particular div and then update the contents of that div -- which I think covers most use cases.

I have made a start on a readme with some example code and a list of all of the available functions. There is a lot there and if you look around eventually you find most functionality that you would want:-


Page Api:
=========

* pageNavigate(url)
* pageReload
* pageDisableEvents
* pageEnableEvents
 
Console Api:
============
* consoleClearMessages
* consoleEnable
* consoleDisable

DOM Api:
========
* domGetDocument
* domGetOuterHTML
* domHideHighlight
* domHighlightNode
* domHighlightRect
* domMoveTo
* domQuerySelector
* domQuerySelectorAll
* domRemoveAttribute
* domRemoveNode
* domRequestChildNodes
* domRequestNode
* domResolveNode
* domSetAttributeValue
* domSetAttributesAsText
* domSetNodeName
* domSetNodeValue
* domSetOutputHTML

DOM Debugger Api:
=================
* domDebuggerRemoveDomBreakpoint
* domDebuggerRemoveEventListenerBreakpoint
* domDebuggerRemoveXHRBreakpoint
* domDebuggerSetDomBreakpoint
* domDebuggerSetEventListenerBreakpoint
* domDebuggerSetXHRBreakpoint 

Runtime Api:
============
* runtimeCallFunctionOn
* runtimeEvaluate
* runtimeGetProperties
* runtimeReleaseObject
* runtimeReleaseObjectGroup 

Timeline Api:
=============
* timelineStart
* timelineEnd

Network Api:
============
* networkCanClearBrowserCache
* networkCanClearBrowserCookies
* networkClearBrowserCache
* networkClearBrowserCookies
* networkEnableEvents
* networkDisableEvents
* networkGetResponseBody
* networkSetCacheDisabled
* networkSetExtraHTTPHeaders
* networkSetUserAgentOverride

Event Api:
==========
Register to handle a given event, use '*' to handle all events.

Event Api Example code:-

    rDebugApi.on('DOM.documentUpdated',function(event) {
        console.log("Event:document updated");
    });
    rDebugApi.on('*',function(event) {
        //fired for all events.
        console.log("Event:",event);
    });

Methods like consoleEnable will turn on console events so you can handle them. consoleDisable and similar functions will then turn off those events.


Ok I think I have earned myself a break after implementing all of that! Module is available in npm as "npm install chrome-rdebug" and on github: https://github.com/sihorton/chrome-rDebug

I guess we now have a full bridge to use in AppJS v2.0!

/Simon

Kevin Ingwersen

unread,
Sep 8, 2013, 1:44:54 PM9/8/13
to appj...@googlegroups.com
Very, very great!

There is just one suggestion: Name. Yes, its a chrome rdebug module, but its for nodejs :). Suggestion: Chrome-rDebug-Node. Reason is, once I am done, we might have a PHP port - which is why I will call mine Chrome-rDebug-PHP.

Otherwise, very well done work. Going to try it out and make my PHP port! ^.^

Now that is basicaly all we needed. Just, that browser-binary. But I think @milani can put one together for us.

Oh another thing that just came to my mind.
We could extend the rdebug protocoll a little, so we actually can tell the appjs window to do certain stuff - like, unhide, hide, resize, move, focus...you know what I mean. Thats something that once it exists you should add to that code as a sort of "appjs extension". :)
Im just throwing in some ideas I randomly get - what in the end happens with them is written in a different book ^-^

Now, to go and make my PHP port. ^^

Simon Horton

unread,
Sep 8, 2013, 1:55:58 PM9/8/13
to appj...@googlegroups.com

The name is for a nodejs module and they dont like you including node or nodejs in the name (part of their guidelines).

If you look at my implementation it is quite regular and I have coded the names and parameters directly from the docs so you should be able to translate to php. This api is not limited to appjs but would work with any chrome browser!

The api is a bit long-winded using long names, parameters etc. I suggest we add an api on top with as you suggest show / hide methods and everything for appjs combined with simpler remote d3bug calls. That way user does not need to know how it is implemented but just what they want done and the remote debug api could still be used outside of appjs.

Simon

Kevin Ingwersen

unread,
Sep 8, 2013, 2:03:51 PM9/8/13
to appj...@googlegroups.com
Well once the PHP port is done, I could realize that "API on top" with the appIO idea I had as you probably saw in my rather long PHP snippet x)

Simon Horton

unread,
Sep 8, 2013, 2:13:06 PM9/8/13
to appj...@googlegroups.com

Yes, are there any changes you would like to help the php port? It looks currently that we will use cef so that means nodejs will still be needed - so php could plug into those api rather than having to duplicate them.

The cgi standard is very well established, maybe I should just upgrade that implementation for you. I noticed you talking about environment variables, they should be available through cgi.

Let me know, maybe start a new thread as this one is getting long now :-)

Simon

Kevin Ingwersen

unread,
Sep 8, 2013, 2:19:09 PM9/8/13
to appj...@googlegroups.com
Well, let's go ahead with the new thread first.

Well I had the binary-browser in my mind still. Depending on what @milani decides to make, I can use the PHP variant to actually strip myself off nodejs (maybe you didnt notice, but I am not reeeally a javascript fan XD). If, however, we must use nodeJS, then my port will only be usable for these that want a debugger/remote for chrome that works from the command line, which PHP does quite well actually. Otherwise, a local run php script can utilize that port to work with the client's opened chrome browser.

Whatever, this is also a nice practice for me here :)

The other layer, appIO, will basically just be laid ontop of your api, shortening osme most-needed things, and adding additional appjs calls that can be done to the browser.

To be honest, it sort of depends on what kind of appJS we get. :) For rightnow, I'll take the practice happily and write a plain chrome-debugger in PHP. I have the rough class-tree down already. Now implementing the AJAX class so I can do some reads and writes as well.

Let's see what we get in the final =)

Simon Horton

unread,
Sep 8, 2013, 2:24:20 PM9/8/13
to appj...@googlegroups.com

Yes that is a good idea. If you write it all in php you can boot off chrome with an app then use remote debugging protocol to control it. You could make php listen to a given port then it could serve css / images / js and so on over http just like appjs does.

Very good to have multiple implementations as it gives more perspective to the design.

Simon

Kevin Ingwersen

unread,
Sep 8, 2013, 2:30:26 PM9/8/13
to appj...@googlegroups.com
That is actually exactly what I will write if appjs appears to be a single binary that is backend independent :3

Chris Banford [Webascent]

unread,
Sep 8, 2013, 3:08:28 PM9/8/13
to appj...@googlegroups.com
Great work Simon! Amazing how quickly this is all moving forward again. Kudos :-)
-Chris


Chris Banford [Webascent]

unread,
Sep 8, 2013, 3:21:23 PM9/8/13
to appj...@googlegroups.com
(and of course, Kevin too!)

Kevin Ingwersen

unread,
Sep 8, 2013, 4:01:36 PM9/8/13
to appj...@googlegroups.com
Simon, care to counter-read this? :)
It's just the rough structure so far.
Am 08.09.2013 um 20:24 schrieb Simon Horton <siho...@gmail.com>:

Simon Horton

unread,
Sep 8, 2013, 4:14:16 PM9/8/13
to appj...@googlegroups.com
That looks great. If you try implementing the $Page->navigate($url) function first then that is maybe the easiest to test with.

For that function you need the websocket connection to the page (something like 'ws://localhost:9222/devtools/page/A4CB0085-8ACD-4E3C-BC53-0BA888EFC4D6'). Then it is not that difficult you just send a message, which is a json object:-

{  "id":$id
   ,"method": "Page.navigate"
   ,"params": {"url": "$pageUrl"}
}

The $id should just be an ever increasing integer you increase with each call, and the $pageUrl would be something like "http://appjs.com" or even "about:blank".

Then you won't get any response back, but instead you will get a message at some time in the future:

{  "id":1, error:{}}

That 1 will match up with the $id that you sent it in before. If it is a command that gets information (like getOuterHTML) then the message will contain useful information. So the most challenging thing to do is to connect up the request / response together using the id's.

Once I had that basic stuff actually adding in all of the functions went quite quickly.

Ok it is late here so I am going to sleep, good luck and talk to you tomorow.

/Simon

Kevin Ingwersen

unread,
Sep 8, 2013, 4:25:46 PM9/8/13
to appj...@googlegroups.com
Well then, I will spend my time introducing the feature as the first, and then I can find the rest. =)

Thanks for the information btw! my code is actualy detecting the URL by its own, from what I was reading. I will do some testing tomorrow. o.o

The increasing id is veeery simple in PHP:

WK_RDP::$id++;

Done, ID increased =)

Kevin Ingwersen

unread,
Sep 8, 2013, 5:00:48 PM9/8/13
to appj...@googlegroups.com
Coooool, google must love me XD

Kevins-MacBook-Air:MacOS Ingwie$ ./Google\ Chrome --remote-debugging-port=6666 --user-data-dir=./
Trace/BPT trap: 5
Kevins-MacBook-Air:MacOS Ingwie$ ./Google\ Chrome --remote-debugging-port=6666
Trace/BPT trap: 5

In other words: SIGTRAP!

Well, I have to find another soltuin for testing the wk-rdp then... x.x Suggestions are welcome.
Am 08.09.2013 um 22:14 schrieb Simon Horton <siho...@gmail.com>:

Kevin Ingwersen

unread,
Sep 8, 2013, 7:33:22 AM9/8/13
to appj...@googlegroups.com

Am 08.09.2013 um 11:46 schrieb Kevin Ingwersen <ingwi...@googlemail.com>:

Hey.

Well as it turns out, we can do a pseudo scope-bridge with the remote debugging protocol. So, that looks like its the direction it's gonna go.

However, there is another thing I am questioning myself currently. As you know, there is a thread/issue open about building appjs - and that gets me thinking about ia32 and x64 - in other words, compatibility with platforms. So, if you added the WK-RDP, would that actualy solve current problems about building and compatibility?

We can use the websockets and alike to open different pages and transfer the scope. But what I am thinking about is the compatibility with other languages. Sure, I can put together a "router" to implement somebodies favorite language (PHP for me). But what would it be, if we could cling any backend, nodejs independent, to appJS? Thats just something I am currently looking into, mainly because of curiosity. Using a little nodejs to set up a base, and managing the rest from other languages, shouldnt be a big problem for the most - after all, nodejs is javascript, which is what we use in the product anyway. :)

I'm gonna look forward to your response tot hat ^-^. Man...im so happy appjs is continuing x)

Regards, Ingwie

Kevin Ingwersen

unread,
Sep 8, 2013, 5:46:39 AM9/8/13
to appj...@googlegroups.com
Hey.

Well as it turns out, we can do a pseudo scope-bridge with the remote debugging protocol. So, that looks like its the direction it's gonna go.

However, there is another thing I am questioning myself currently. As you know, there is a thread/issue open about building appjs - and that gets me thinking about ia32 and x64 - in other words, compatibility with platforms. So, if you added the WK-RDP, would that actualy solve current problems about building and compatibility?

We can use the websockets and alike to open different pages and transfer the scope. But what I am thinking about is the compatibility with other languages. Sure, I can put together a "router" to implement somebodies favorite language (PHP for me). But what would it be, if we could cling any backend, nodejs independent, to appJS? Thats just something I am currently looking into, mainly because of curiosity. Using a little nodejs to set up a base, and managing the rest from other languages, shouldnt be a big problem for the most - after all, nodejs is javascript, which is what we use in the product anyway. :)

I'm gonna look forward to your response tot hat ^-^. Man...im so happy appjs is continuing x)

Regards, Ingwie


Am 08.09.2013 um 06:35 schrieb Morteza Milani <mrtz....@googlemail.com>:

ashish negi

unread,
Sep 11, 2013, 7:50:14 AM9/11/13
to appj...@googlegroups.com, ingwi...@googlemail.com
Has this discussion moved to some other thread ?
...

sihorton

unread,
Sep 11, 2013, 6:49:22 PM9/11/13
to appj...@googlegroups.com, ingwi...@googlemail.com
Hi Developers!

I got a very fun email this morning, Ashish Negi had submitted the first pull request to chrome-rDebug (i.e. the new bridge code) and had implemented the call to chrome to find the websocket url to connect to with the web socket protocol. This is really one of the things I like the most about open source when suddenly other developers add new things and improve the code. So thanks to Ashish we now have both the full debug protocol and we can automatically connect up to the correct websocket address :-) This thread is quieter just now because we are waiting for the new appjs binary, but it is like the lull before the storm, once that lands this thread will explode again with creativity.

In the meantime I have asked Morteza Milani to give you access to the wiki so you can document the build process and other ideas for documentation.


/Simon

Simon Horton

unread,
Sep 11, 2013, 10:00:10 AM9/11/13
to appj...@googlegroups.com, Ingwie Phoenix

No, we are waiting for a binary to appear to being playing with ;-)

Otherwise we can do experiments with an off the shelf chrome.

Simon

--

Simon Horton

unread,
Sep 11, 2013, 12:03:09 AM9/11/13
to appj...@googlegroups.com

I guess the question is what API do we want / need that is not covered by the remote debugging api.

You can open new windows with window.open in browser js. You can get browser to connect to your "application" socket, i .e. opened by php which can then implement any api you want.

In a similar way nodejs can open socket to provide an api to access database / files and do things not allowed in the browser sandbox. This api could be mirrored by php and other backends.

We can then have the "webserver/cgi" part, navigate to http://localhost:9098/helloWorld.php and you can then execute php page and return result helloWorld.py couod run python.

Simon

Kevin Ingwersen

unread,
Sep 14, 2013, 8:14:12 AM9/14/13
to appj...@googlegroups.com
Hey Simon.

Some missing api would be the actual frame - i.e. frame.fullscreen, frame.minimize and alike. Thus, I dont know if the wk-rdp actualy sends a ready-event, so we could do stuff from our backend side as well. In all general, the native-api would be missing yet.

The other api i personaly would want is the command-line api. So I just have a binary called appjs, call it from my PHP script (pseudo-command line), and have the both talk with each other.

Another thing that would be cool is, if the browser would send back messages when the user navigates to another site. Could be useful imho! :)

Regards, Ingwie
PS. Heared anything from Morteza yet bout the binary?

Simon Horton

unread,
Sep 14, 2013, 8:28:38 AM9/14/13
to appj...@googlegroups.com
Hi Kevin,

Events are already covered by the debug protocol. So for example if you issue the network enable message then you will start receiving events saying when each file is being downloaded and how much time it took (think of the firebug network tab), as I recall there is a page navigate event but don't quote me on that! There is more in there than you realise by reading the documentation and I have not had time to play around with it much yet. Good thing is I have implemented the full spec with all messages and events so that means if web developer tools can do it then you would be able to do it as well with a bit of hacking (since we use the same underlying protocol).

The advantage with the web debug protocol is we can use it on any page on the internet. It might be interesting to implement a "greasemonkey" style script, i.e. using the debug protocol monitor the urls a user is navigating to, then if they visit certain sites inject a script tag into the page that loads and runs javascript. That javascript could then provide additional api's or perform actions on the page.

/Simon


Kevin Ingwersen

unread,
Sep 14, 2013, 8:32:02 AM9/14/13
to appj...@googlegroups.com
Hey.

Well that seems to cover my needs then :3

Now, we then just need the frame apis, to like, change size, maximize or even fullscreen it. :)

Hope Morteza comes out with a binary soon. o.o...

Regards, Ingwie

Kevin Ingwersen

unread,
Sep 14, 2013, 9:26:34 PM9/14/13
to appj...@googlegroups.com
I just got some very random idea. Really, very random... but possibly useful!

I currently imagine appjs as a single, standalone, executable which is backend independent. and can be called from the command line. For that case, I have a few switches and options that could possibly be passed to appjs once it is invoced from another backend - such as nodejs' child_process.spawn or PHP's system function (well, C too, if somebody wants to? x3)

Usage appjs [FLAGS/OPTIONS...]

--page-method=[http/ws] Defines how the pages that need to be displayed should be retrieved.
Type can be:
http: The browser-window will act as a display to a given URL such as a local web-server
ws: The pages may be queried thru the WK-RDP/WebSocket.
--url=URL The url the data should be requested at. I.e.: --url=http://localhost:666 OR ws://localhost:1234
--pid-file=FILE Path to write a PID-file to. This may be used to be read from another process to kill the browser, or controll the process.
--fullscreen=[true/false] Wether to enable fullscreen or not. Default is false.
--titlebar=[true/false] Enable/disable titlebar. Default is true.
--error-page=FILE HTML file containing a static error page.
--ws-file=FILE Write full address of WK-RDP address to given file. Useful for lazy devs, to read it and use it ;)
--wk-rdp=PORT The port appJS should open up for the remote debug protocol.
--show=[true/false] Show the window as soon as possible. Can be shown via api, i.e. in the ready-event. Default is true.
--user-agent=STRING The user-agent to use for appJS.
-V, --verbose Be verbose.
-v, --version Version
-h, --help This help...obviously.

Hopefuly this is useful for Morteza or anybody else...dunno - just thought i'd drop this in~ :3
Am 14.09.2013 um 14:28 schrieb Simon Horton <siho...@gmail.com>:

raitucarp

unread,
Oct 1, 2013, 9:27:57 PM10/1/13
to appj...@googlegroups.com
This is totally Awesome. Can't wait for stable version (or complete documentation).

I think you guys should post this project on KickStarter, anyone can invest you, and you can find the team work with you (with the money from kickstarter will pay them).

These are great possibilities of DeskShell:
- Since node-webkit is node.js + webkit, It's use node.js as the main approach, which is javascript. Deskshell can do it more better, It's can be agnostic, It can embed other programming language ie; python, ruby, php of course javascript as the main backend (If you know what I mean)
- DeskShell use new approach for developers. Easy developing with current Web Technology (without confusing to build, or packaging it)

sihorton

unread,
Oct 2, 2013, 4:37:21 AM10/2/13
to appj...@googlegroups.com
I think you are catching the idea with the deskshell project. The major parts of the PHP port is basically working but it needs to have a lot of the end user features added in.

Status at the moment:-

  • Windows / Nodejs: There are no known bugs so I would say jump in and start building.
  • Mac / Nodejs: If you are willing to checkout using git then you can get this port working, but the pre-built download does not work and there can be problems with paths etc. The latest features from the windows port are not all available on mac and there are also usability issues (like the menus that are displayed etc). Basically a whole lot of clean up and polishing is required. However remember that all of this is written in javascript so if you have a mac and web skills then get hacking and help us complete the port.
  • Mac / PHP: not yet released to repository but very major features like php websockets and multi-threading have been completed. This means that the php backend will be able to do the same as the nodejs backend. The various pieces still need to be joined together but the hardest part of the work has been done.
  • Linux / Nodejs: Can be run and applications opened fine on ubuntu. Is behind windows port since we don't have any community involvement or feedback for this port yet. Therefore we are concentrating on windows / mac ports and can update the linux port by copying over features once they are released on the other ports.
Documentation is supplied by the default application that launches when you run deskshell directly. This contains a number of demos which are already as good as for appjs and it also contains documentation of api's and the .desk file format and so on. This is all in HTML so it is really easy to update and improve, try downloading and read it and ask for any clarifications that are needed and we can improve the documentation.

/Simon

ma...@jetsonsys.com

unread,
Oct 15, 2013, 5:50:57 PM10/15/13
to appj...@googlegroups.com
Hmmm, guess I was out to lunch on all this discussion. Perhaps, I should have spoke up. I've gotten around the limitation of node blocking UI / UI blocking node etc. by building my client side APP which exercises API endpoints which run in separate processes. I have a "rest service" and a "web socket" service.
Each "resource" in the API is serverviced by a separate instance of a web-worker in its own process. These services communicate to "web worker" sub processes which are implemented using a hacked version of node-webworker:

https://github.com/marekjulian/node-webworker/

the above being a port of:

https://github.com/pgriess/node-webworker

The web worker communication utilizes web socket protocal over Linux domain sockets as the original implementor created.....

I got to this point after reading alot about efforts to introduce threading into Node, such as:

https://github.com/audreyt/node-webworker-threads

for example.

This has worked out well for me. The client code utilizes HTTP and websockets, all web standard. Some resetful endpoints may trigger an action which could take a long time, like a file import ( as POST /importers ). The client listens for messages over a web-socket to monitor the status of this process, ie: import.started, import.<something>.imported, import.completed, etc..... Then the client can respond appropriately.

All the actions which would not be possible in the browser or could take a long time and block are executed by some API endpoint or triggered by some endpoint.

I'll have to digest the direction you guys are taking things!

Marek

On Thursday, September 5, 2013 11:13:30 PM UTC-7, sihorton wrote:
Hi AppJS Developers.

This will be a long post, take a break get a coffee and prepare yourself!

Background:
=========

I remember many years ago discovering that netscape navigator could read files directly off the local disk using the file:// protocol. At that time I was building desktop applications in visual basic. These were quite good and deeply integrated into the OS but the interface was nothing compared to dynamic html (as it was called back then in the golden olden days of the internets). Suddenly I had the opportunity to have a beautiful and flexible interface I could throw up in a couple of mins running on the desktop. Using iframes I could even list the contents of the disk and navigate through it with a nice interface. Of course it was a hack and a horrible security flaw so after a couple of years suddenly the hole was plugged and those hacks stopped working.

I have tried out many different hacks, tricks and technologies through the years always trying to reach the same goal really:- I find web technologies very natural, powerful and rapid to develop and deploy. When I find myself building a desktop application (for example a file monitor that automatically uploads changes to a remote server), then I always want to have a desktop application with full access to local disk etc, but I want the interface to be html and web technologies.

What is needed is a "browser" giving that wonderful html interface and web technologies, but it should have some security features turned off so local disk access and database is possible and it should not auto-update -- if I build an app I want it to run and work forever even if google depreciates those google gears apis I used to build an app 3 years ago.

AppJS:
=====

When I discovered AppJS I found a great solution. NodeJS is very powerful and awesome for async programming and chromium is a very modern and powerful browser and gives a wonderful interface development platform. The magic is that both nodejs and chromium use the same v8 javascript engine, so with appjs you bridge the two v8 contexts and get the wonderful solution we all know and love.

Technical Limitation:
===============
Unfortunately we have reached a technical limitation in appjs development. As wonderful, revolutionary and just plain awesome that bridging the nodejs and chromium v8 contexts was there was an unfortunate and unexpected side effect. Since both contexts are running in the same process, heavy operations in the browser will block operations in nodejs. Likewise heavy nodejs operations will block chromium. This is very unexpected to web developers and therefore causes problems. If for example you use CSS3 animations to spin and move items in the interface around then the animations become juddery and pause as nodejs performs heavy operations. Everyone just thinks hey it should not be like that!

The obvious solution is to put nodejs and chromium in their own processes or threads so animations can run at the same time as nodejs is doing whatever the application needs. The async nature of javascript (it does not support threads as native objects but uses callbacks instead) means that altering appjs to run two separate threads but still bridge one v8 context to the other has proved to be extremely difficult. As you have noticed the number of open issues on appjs has risen and the forward development of the platform has slowed while this issue has been tackled. Unfortunately as it stands today it has not been possible to move to a two thread/process solution and get a working internal bridge between the two v8 contexts.

I have discussed appjs with the head developer Morteza Milani. Due to the technical limitations of the current appjs technology appjs as it is today won't be getting new updates. He has begun pointing people to use node-webkit as an alternative to appjs and several developers have moved over to that project.

A New Direction:
============
I think that we mostly attract web programmers to the appjs project. It is mostly web developers that need or want to develop a desktop app using web technologies that get involved. There are fewer hardcore C++ programmers among us and that means the burden of development falls very heavily on a few shoulders.

My proposal is to get all of those javascript developers hacking on the appjs platform itself. To do that lets dial back the C++ and try to get as far as we can with javascript and web technologies. Where we hit something we cannot get around we can build something in C++ and expose it as an api to call from javascript. If we find an alternative using javascript lets provide that as well so the platform is more hackable to the largest number of people. The one exception to this rule is nodejs native C++ modules, I think we can just use them if available or provide a choice between C++ module and an equivalent javascript module.

Maybe you are thinking that this will mean that we will only be able to have a very limited and essentially crippled platform. However the more that I have thought about this approach and the limitations the more I think it is going to be capable of. Since nodejs has native C++ modules that are available to javascript and an amazing number of npm modules available this is not the limited platform you would at first think.


Concreate Plan:
============
This new direction can succeed if developers get excited and have some fun trying to take this idea as far as possible. This is an open source project so we can all benefit from each others solutions and experiments.

What I am proposing is that we have an "off-the-shelf" standard chromium binary on the disk. We also have a nodejs binary on the disk. Nodejs starts and boots off chromium and we have then solved the nodejs blocks chromium and chromium blocks nodejs problem we got stuck on. We also magically get all of the latest web technologies in chromium "for free" and if you want some new cutting edge technology get hold of the latest chromium binary that provides that functionality, drop that into the folder and take advantage of the functionality straight away. Likewise want to use nodejs 0.10 then just drop that binary in, no compilation issues, no compatibility issues.

With this new design we just got lots of things for free we could not have easily before. However we have also lost something major: we lost the internal bridge between the two v8 contexts and we lost the cross platform native desktop integration.

Lets start from the new design of having two binaries and then lets work through and develop solutions to connecting the nodejs backend to the browser frontend, and try to make the end solution as close to a native application as possible.

I am going to be using this setup to build a number of desktop applications for my own use. If we all start working in this direction then I am sure we can actually come a long way.

Short Discussion:
=============
I just want to answer some obvious questions people may ask about the new approach.
1) Communication:- nodejs opens a websocket, chromium is given the page to load and display on startup and this opens a websocket back to nodejs. Now you have two way communication and can pass json messages between the contexts. Chromium also reads its files from nodejs as normal http communication.
2) Packaging:- I have previously developed code that lets you take your "site" i.e. the browser stuff and the nodejs stuff and wrap it all up into a single package file. You can then have a single install of the nodejs and chromium binary that can run the package files.
3) Run code from node in chromium:- just take your function as a text string and send it to chromium, it can then eval the code.
4) Access DOM from node:- Use the remote debugging protocol. https://www.webkit.org/blog/1875/announcing-remote-debugging-protocol-v1-0/ It is possible to remotely connect to a running webkit and then manipulate the dom, change it, iterate over items and everything that you can do in firebug or webkit inspector. The only problem here is security. Hopefully it would be possible to make chromium only allow remote debugging from nodejs. If you search the web you can see people have created remote interfaces that can debug javascript on the fly and evaluate commands as you type them in. So actually this would give us something like the original appjs bridge. http://jsconsole.com/remote-debugging.html. Protocol is json format so perfect for a web developer to hack with.
5) Native functionality: On linux connect into DBUS, there are already npm modules that can be used. Create a javascript shim that provides an API and then uses dbus to communicate with the system. On windows you can open a powershell process and then pipe commands to it and have access to all of the .NET objects in windows. Create a javascript shim / api and then other platforms can implement the same or similar api so desktop app runs cross platform.
6) Desktop Drag and Drop: create a native executable that opens a small window with a "drop here" icon, when the drop occurs do a POST to nodejs with the filenames of the files and folders that were dropped.
7) Private Port:- Chromium app can have a client certificate, nodejs can refuse to talk to anyone connecting to the socket without the client certificate (problem with this is someone can just copy the client certificate from the chromium folder, anyone have a solution?).
8) Cross platform:- lets run on mac / linux / windows as we do today, allow native integration to the desktop and special platform functionality through api's so the desktop applications can be as good as possible.

Basically when you think about it we can work around many problems and get a lot of functionality for this platform. If we get a lot of contributions then the platform can develop quickly and I believe be very useful as a rapid desktop application platform.

Call for Help:
=========
We can all sit and hack our own desktop applications but it is even more fun to do it together. It is also a great way to learn and develop as a programmer. If you are a professional developer you will find open source programming is different to commercial programming and can be fun to do as a hobby.

If you would like to be able to rapidly build desktop applications using web technologies then this is the project for you. There are literally hundreds of different technologies that we could use to reach that goal. There are chrome packaged apps, phonegap, node modules and future technologies and api's that have not been thought of yet! Think what your future apps would need and then begin coding and hacking some form of solution. Show it off to everyone else and inspire them to hack something even better. Create a little pull request and get your changes into the project and mention you are an open source committer in your next job interview!

Today I am not presenting any new code since I want to hear what everyone has to say first and hear what ideas you all have for future appjs direction. That feedback can then affect and steer how we build the first prototype. Having said that it is quite easy and would only take a couple of hours to have a nodejs binary, chromium binary and websockets code talking together to be the first implementation. Then from that we can experiment and add a lot of functionality as developers need it for the projects they are developing. I can contribute a packaging solution and others can improve on it.

There are many awesome developers that have contributed and used appjs in the past and you are very welcome to start hacking on appjs itself. We would really like to encourage more contributions from everyone.

Maybe you have never contributed to an open source project before or used github or know what a pull request is. No problem everyone has to learn at some time, it is much easier than you would expect!

I know there are many companies and consultancies that are using appjs. This is a great opportunity for you. You can contribute code and move the platform so that it meets your needs while benefiting from everyone elses contributions and testing of the code in daily use. If we had 3 or 4 developers with some time on their hands we would get a lot done.

It kind of goes without saying but this is open source so no matter how clever you are, or how amazing the idea, demo code wins over theory every time so if you have a great idea then get your keyboard out and put together a very bad first demo of the concept and then take it from there. Code always beats nice theoretical ideas!

The only thing that beats code is of course documentation, tutorials, example code and demo apps. This is so important since this is how we all learn about the platform. If you want to make appjs accessible to others then that is amazing and very important.

I will finish by saying that there is a lot of room for new people so if you have time to contribute then you are more than welcome to the team. Also since I have not yet presented any code you can get a head start on me and hack something together yourself along these lines over the weekend and then show it off to us all ;-) I have said that demo code beats ideas and theory so go for it and your code could be the first prototype!

/Simon

Simon Horton

unread,
Oct 15, 2013, 6:29:19 PM10/15/13
to appj...@googlegroups.com

Hi Marek,

Wonderful! So you have found a standards way around the UI locking problem. Very interesting indeed. If webworkers are implemented and working as a module in nodejs then I think we should add them and make them available in deskshell.

Actually the current deskshell design could still run the existing appjs implementation.  Since you have solved the UI locking problem we could create a deskshell example using webworkers and then appjs. That might even be preferrable to using chromium for some setups.

As a simpler version of your solution I guess a nodejs script could start off a webworker to run the "appjs router" i.e. built in webserver and websockets in a separate thread. Then the script can open appjs window and be able to pass messages from browser to webworker code. That way you prevent UI lock and have just one webworker for beginners.

I guess a minor limitation is that webworker code cannot access browser DOM -- same limitation we have with deskshell, so changes would end up going via a socket call or even using the chrome remote debug protocol like deskshell.

Well thanks for sharing this solution with us we can definitely include it in deskshell (since it is the appjs v2 project). Then if we have multiple solutions available we can see what gives best solution in different situations. My spontaneous reaction is that this is compatible with our direction and sounds like a good solution. We are already thinking of supporting multiple backends and frontends and having some form of plugin structure so I can see one deskshell example setup being exactly along the lines of what you are suggesting.

Are you willing to create an appjs demo project for us that shows example use of webworkers? If you did that we could take the code and then see how we can change deskshell to be compatible and see where we end up.

Open Source development is so interesting as new ideas and directions come out of the blue all of the time. Congratulations on getting around the UI locking problem!

Simon

--

ma...@jetsonsys.com

unread,
Oct 15, 2013, 8:53:49 PM10/15/13
to appj...@googlegroups.com, siho...@gmail.com
Hey Simon

Its been a tough year for me personally so I don't know when I'd get to throwing together a sample APP using my solution. But, I would love to. I think of something silly.

I have however NOT kept our Apps desktop code lockdown on gitub. You could take a look at the following to get an idea:

https://github.com/jetsonsystems/PlmFrontEnd/blob/master/Middleman/source/js/app/photo-manager/views/home.js

Notice the ajax call in response to the open / save dialog to select files that will be read of the filesystem by the API.

This module firles off web workers for all the API endpoint resources:

https://github.com/jetsonsystems/MediaManager/blob/master/MediaManagerAppSupport/lib/ApiWorkers.js

There's docs on the API here:

https://github.com/jetsonsystems/MediaManager/tree/master/MediaManagerApi/documentation

Unfortunately, I haven't ported the websocket based "notificaitons API" stuff too github marekdown yet. But the rest stuff is just a bunch of stuff related to image files.

The goal of this was to build a business app that dealt with docs and other stuff. A media - manager of was the first step to get a desktop platform in place.

I'll see what I can do about a very simple to follow example.

Marek

Simon Horton

unread,
Oct 16, 2013, 11:47:37 AM10/16/13
to appj...@googlegroups.com
Hi Marek,

Only do something if it is fun and you have the time, no pressure from us at all.

Maybe the demo could be super simple, a CSS3 spinning graphic and then two buttons. Click the first one and it runs some CPU bound code directly in nodejs so it blocks the animation and then the second button runs the same code in a webworker.

I guess we could use the code from the infamous "Node.js is Cancer" article (http://pages.citebite.com/b2x0j8q1megb).

function fibonacci(n) {
  if (n < 2)
    return 1;
  else
    return fibonacci(n-2) + fibonacci(n-1);
}

and then handle the first button request and run:-
fibonacci(40);
and then the second button request does the same with a webworker. Press first button and graphic stops spinning for some time, press second button and graphic continues spinning :-)
I just searched google and found the following css3 demo for example:http://www.alessioatzeni.com/wp-content/tutorials/html-css/CSS3-loading-animation-loop/index.html

/Simon
It is loading more messages.
0 new messages