WebSockets noob working with Railo - linux

I am admittedly a complete noob in all things server, Linux, and websockets. I finally managed to set up a VM running Apache, Tomcat, and Railo that I could connect to and serve up CFM pages, all the while learning UNIX command line navigation, server theory, etc, etc...
Here's my problem -- there is only one Railo websocket extension and it is super rinky-dink (I had to modify the CFC just to get the service to start) but I can't get a websocket connection up (I keep getting "unexpected code 200" in Google Chrome). There is minimal documentation, which is not helpful at all.
Basically, I am trying to do some prototyping for a future project that will use websockets. I like Railo for its speed, security, and excellent ability for very database heavy operations. I am interested in Node, but don't know how to get the same security and DB functionality out of Javascript as I can with CFML.
So I have a couple questions: what are my best options for WebSocket servers? Should I be trying to use Apache and/or Tomcat? People keep saying it's totally not worthwhile to have something like Node.js running the websockets portion and something else doing the heavy lifting behind it -- why is this? I'm more than happy writing WS handlers in whatever language if I can just get a nudge in the right direction, some excellent tutorials (I can't seem to find much in this department), or good feedback on how to, from the ground up, set up my Linux box to handle websockets -- and preferably how to handle both websockets and a robust language like Railo.

The Railo extension works fine for me.
What about submitting some test code so that we can debug it? Of course the websockets projects is very young and in full deployment. So feel free to fork and submit patches or suggestions.
You have plenty of options:
Railo Google Group
https://groups.google.com/forum/?fromgroups#!forum/railo
Github Extension Repository
submit a but in the Railo Jira bugtracker

The main problem of node.js is that it's mono-thread : you won't be able to do background tasks using it and local IO will block your server.
A solution I use is Go. It's very fast, has very good concurrency features and has integrated websocket and json libraries (sample : http://gary.beagledreams.com/page/go-websocket-chat.html). An efficient web application server is made in a few dozens lines of Go. You'll find that there is still much less documentation on internet than for java or even node.js through.
There are a few implementations of websockets in java but as I'm in the process of switching everything I had in java to Go I hadn't tested them. I know I use Google gson for the json encoding in java and it's very good.

The "unexpected code 200" is caused by Railo's web socket server sending an outdated response. They changed the web socket spec and Chrome uses the newer spec.
The problem seems to be caused by chrome & co implementing the new spec, "draft-ietf-hybi-thewebsocketprotocol-17". It requires the server to respond with "HTTP/1.1 101 Switching Protocols" rather than 200 OK.
The solution here would be to either update the Railo web socket extension yourself or use some other solution:
Here is a complete demo of a web socket chat server written in PHP.
http://www.flynsarmy.com/2012/02/php-websocket-chat-application-2-0/
I have used this myself to implement a real-time HTML chat served from an Arch Linux machine that I had lying around. Configuration consisted of simply setting up Apache and PHP then changing the IP address in index.html and in server.php to the external ip address of the server machine.
This flynsarmy demo includes a recent version of PHPWebSocket which is an open source web socket server written entirely in PHP and contained in a single file. The demo hooks into three callbacks: connect, message recieved, and disconnect.
The important thing to note, for me, was that the web socket protocol supports text only, not binary so while extending it for my own chat app I had to implement my own commands to help control the server. Commands in my case looked like this:
!kickusers: username, another_username, a_third_username
My server code would check the first character of all messages for a '!' and if present would treat it as a command. Then I slice up the string to get the command "kickusers" and a list of users to kick. Then I call the appropriate kick function and pass it the array of usernames.
Since my scenario was a chat client this meant that the user could literally type this command into chat and the server would accept and respond to it.
The way all this is deployed on my server is like so:
I have Apache serve the index.html page when the user goes to that location on my server in their browser. The only purpose Apache plays here is to give index.html to the client who requested it.
The index.html page contains html to display the chat and javascript to send and recieve chat to/from the server. Basically, index.html is simply a chat client written in HTML and Javascript and it runs in the browser.
I run server.php via ssh on the server to start up the WEB SOCKET server (totally separate from Apache) which just sits there and handles chat stuff like echoing text to the other connected clients etc.
Though the Arch wiki on installing Apache and PHP is specific to Arch in the way that you install the Apache and PHP packages the sections on configuring Apache and PHP apply to all. I'll save you the google query and give you the link here if you like: https://wiki.archlinux.org/index.php/LAMP
As for prototyping, the reason I gave the link to Flynsarmy's chat demo is because his comments are helpful, he wrote a blog about it, and it comes as a very simple yet complete example of how to do something with web sockets in php.

Related

How to connect angular2 server side with php

I recently bought a new template for my site written in angular2, i did a short course on it and started to work and everything fine.
Now come the the part where i try to connect it to my DataBase and i cant figure it out...
after a little bit of reading i saw that i need to use nodejs in order to speak with the server side, is that true?
can i use php or i must use the nodejs api to work with my Db?
am i missing the concept of the angular2 or something? can someone post a basic script of angular working with php example , i just cant find it.. :(
thanks a lot :)
The most common scenario is that you use the Http service in Angular that makes XHR (Ajax) requests to the server to fetch data (not HTML).
You can use any server that is able to receive, process and response to XHR requests. Therefore PHP is as suiteable as node.js (or .NET, Java, or any other web server)
See also https://angular.io/docs/ts/latest/guide/server-communication.html

Access a local IBM Notes application with default system browser

I am developping web applications using the Xpages framework from the IBM Lotus Notes technology.
My users don't use the embedded Notes Client browser, but use a regular modern browser (Firefox, Chrome) to browse Notes applications.
Everything is ok when the user has an internet connexion, he can access the application on the online server through his favorite browser.
However some of my applications need to be used Offline, in local. When a user works in local, he opens the IBM Notes Client, go to his workspace and click to open an application locally. Then, the Notes Client runs a http server on a random port and open the application with the embedded Notes Client browser.
What I want to achieve is to be able to open the application on a regular browser (Firefox, Chrome), by just using the default system browser and not the embedded Notes Client browser.
Here is what I tried without success :
With window.location.href I get the port where the local http server runs and the path to the page that is opened in the embedded Notes Client browser. I get this kind of result :
127.0.0.1:54428/xsp/Gfn/CoffeShop.nsf/xp_home.xsp?OpenXPage&&xspRunningContext=Notes
So I just keep the interesting part :
127.0.0.1:54428/xsp/Gfn/CoffeShop.nsf/xp_home.xsp
Now I need to pass the session id has a parameter of this http request so the browser will have the right to access the application. I get the session ID with the following :
facesContext.getExternalContext().getRequest().getSession().getId()
From this I get an ID and I build my complete http request :
127.0.0.1:54428/xsp/Gfn/CoffeShop.nsf/xp_home.xsp?SessionID=ID-fae7aca8f062023972fe35e5909b0106f44ba2ae
But when I try this into a regular browser, instead of getting the page I get an error 500. If I look at the log of the server, I see the following error message :
Exception Thrown
javax.servlet.ServletException: The request is not coming from a trusted Rich Client part
But I am sure my ID is correct. I tried to investigate this on the internet but no success for now, I would be happy if someone has an idea about what do I miss? Or maybe another way to open a local application in the default system browser?
Thank you!
In short, you can't. This is disabled by security restrictions.
But maybe you should think again about a XPiNC application: With 9.0.1, the underlying XULRunner component was upgraded and supports now HTML5 and a lot of the "newer" features.
It matches Firefox 10.0.6, here are the HTML5 test results:
https://html5test.com/s/555ae51ca555ac7b.html
The only reasonable action you have at you disposal is to install Domino designer on the clients. Then you get the nhttp task that serves to a standard browser (you might get away analysing what nhttp needs and only install that part).
The caveat there: the local nhttp does not support authentication. So you need to hack around it (e.g. copy data back and forth between the local NSF and the properly secured one).
Alternative you could try the approach I took with vert.x (should work with any Java container, but then you won't have any XPages, just raw Domino data.
Danielle pushed that forward with the Crossworlds Project - which might be what you need.
Stephan says it as it is: the way you are considering is just going to cause you huge headaches.
If offline capacity is a must, have you thought about creating a pure Notes-Client application? That would certainly be far easier.

How to access NodeJS data through cakePHP?

Dummy question here but I haven't found any answer on the web for now.
I'm working on a cakephp website, installed on a Raspberry Pi, which is supposed to be able to connect wireless-ly through a local network to an Arduino YUN, get its components list.
For example :
"A LED is connected on ports :
Input : 2,
Output : 6;
and is currently on"
And change the input value :
"turn the LED off"
I'm not supposed to reload the webpage to see the change occurring.
So I figured out I needed NodeJS to send/receive the informations with websockets but I don't know how to connect NodeJS -running on its own webserver- to cakephp.
I'm a complete rookie with NodeJS, just did a few tutorials earlier, so I'm stuck here.
Does anyone know how to deal with this ?
Thanks in advance,
There are a few different libraries you can use to connect to the node server.
http://elephant.io/
https://github.com/bergie/dnode-php
You can, of course, just fall back to sending http requests (curl) from your cakephp app to the node server.
I have a few discoveries to add that may help some people.
While searching more deeply on DNode and elephant.io I found a cakePHP plugin called cake_websocket which make use of socket.io.
Seems to me that it is an equivalent to elephant.io specialized in cakePHP (while elephant.io is 'just' PHP).
I hope it can help someone !
Instead of using any library.
You can try iframe tag with src to your 'node.js' view.html.
So, listen for events on view.html which are triggered from your 'cakephp' view.html
So, you will have cakephp->view.html talking to node.js->view.html which is connected to node.js->index.js(server)

Allowing cross-domain calls with Yeoman (1.0) grunt server

I've been using Yeoman 0.9 up until yesterday when I decided to use the beta 1.0 release on OS X. I use Yeoman to develop an angular app.
With the Yeoman 0.9-->1.0 migration of my app done and working, I'm now keen to extend the dev server fired up by yeoman grunt server to allow me to make cross-domain calls to an API developed by another team, hosted on another server, where they've already allowed cross-domain calls. Up to now we've been using a fake http backend courtesy of angular.js.
--An aside--
If anyone's reading this looking for a quick solution, we got cross-domain calls working by passing the --disable-web-security option to Chrome from the command line using this approach on OS X with Chrome, but it turns off security for all of Chrome (thumbs down) and we can't get Chrome to fire up as a new instance anyway.
--End aside--
Through some digging I found this Stack Overflow post (via the answer to this post) giving me a pretty good idea on what I need to do to get grunt server allowing cross-domain calls.
It essentially involves adding a middleware component to connect to allow alter the headers so that "Access-Control-Allow-Origin" is set to "*" or whatever one likes.
Knowing nothing about Node.js, I can see the change alluded to in the post needs to be made somewhere in the many files created by Yeoman, but where? I've done some raw string searches for "app.configure" and "connect.listen" within the "node_modules" directory set up by Yeoman but I come up with a number of hits, most of which are from examples bundled with the modules and it isn't clear to me which I should edit. In case it helps, here's a snapshot of the directory structure for my angular app:
If anyone can give me some pointers on where these changes may be made I'd really appreciate it!
Solved sans messing around with node using the approach in this github pull request: http://github.com/angular/angular.js/pull/1454
You can use Apache proxy and connect your REST server with gruntjs(angular.js).
Apache would do this:
proxy / -> gruntjs
proxy /service -> REST server
you would use your application hitting Apache and angular.js application would think that is talking with itself so no cross domain problem.
Here is a great tutorial on how to set this up: http://alfrescoblog.com/2014/06/14/angular-js-activiti-webapp-with-activiti-rest/

Pitfalls of accessing a webserver on 127.0.0.1 from js with a public site

I'm thinking about exploring the idea of having our client software run as a service on a high port and listen for simple http GET requests from 127.0.0.1. The theory is that I would be able to access this service via js from a web page that is served from my site.
1) User installs client software that installs itself as a service and waits for authenticated requests on 127.0.0.1:8080
2) When the user hits my home page js on the page makes an xhtml request to 127.0.0.1:8080 and asks for the status
3) The home page then makes another js request back to my web server sending the status that it received.
This would allow my users to upload/download and edit files on a USB attached device in real-time from a browser. Polling could be the fallback method which is close to what we do today.
Has anyone done this and what potential pitfalls are there? Will this even work?
I can't see any potential pitfalls. I do have a couple of points however.
1/ You probably want to make sure your service only accepts incoming connection from the local machine (127.0.0.1). Otherwise, anyone could look at your JavaScript and figure out that it's talking to [your-ip]:8080. They could then try that themselves from a remote site (security hole).
2/ I wouldn't use port 8080 as it's commonly used for other things (alternate HTTP servers, etc.). Make it configurable and choose a nice high random-type value.
3/ I'm not sure what you're trying to do with point 3 but I think you're trying to send the status back to the user. In which case, why wouldn't the JavaScript on your home page just get the status in a single session and output/update the HTML to be presented to the user? Your "another js request back to my web server" doesn't make sense to me.
You may not be able to do a xml http request to 127.0.0.1 as XMLHTTPRequest is usually limited to the same domain as the main content is being served from. I'm not sure if this restriction applies if the server is on the client's machine. That being said, you could still create a <script> tag that had the src pointing to 127.0.0.1, and have the web server return some Javascript to run. If you only need a simple response, this could work well.
I think it is much better for you to avoid implementation of application logic in JavaScript and html. Once user clicks button on a web page JavaScript should send request to your service and allow it do the rest of the work.
You could have problems with step 1 (Client installs itself) depending on your target user base.
You will need a customised install for each supported environment (Win2K, Vista, Linux, MAC OS 9.0/10.0 etc.).
If your user is on a locked down at work PC this simply wont be allowed.
To some users this might look distressingly similar to a trojan unless you explicitly point out you will be installing software that runs as a service.
You didnt mention an unistall procedure. Users resent "Adobe" like software which installs itself and provides no sensible un-install options
Ohterwise the approach is sound, and, there are are couple of commercial products out there that use exactly this approach!

Resources