NodeJS chat server interacting with non-node hosted html page - javascript

The node.js chat example is ubiquitous. However, they all serve the static html page with which the chat feature is integrated.
What about an html page that is served via apache, php, .net, or other which interacts with a node.js based chat server. How would this be implemented?
For instance, the html page contains a form used to login. The form's action points to the node server which provides the authentication and message handling. How does this chat server communicate with the client-side when it is not also providing the static html content?

Yes, it's possible. If I understand you correctly, you'll probably want to use this approach:
Run the apache server on a different port from the node.js server, and have the static server serve the chat page. Then, you have two main options for how to get data from the static page to the node.js server: either use XMLHttpRequest directly from the static page with CORS (you'll need it because you're running from different ports, but it's still possible to have CORS allow from different ports on the same domain but nothing else, so it can still be secure), or have an invisible iframe of the node.js page on the static page, and then send data to it with postMessage, and then the iframe (which is on the same port as the node.js server, as it's being served by node.js) will forward the data from the postMessage to the server with XMLHttpRequest
You can also do a proxy, but it won't be as good for this type of situation I think, because if Apache is running the proxy, it completely erases how node.js does well with comet and things, but if you run node.js as the main server proxying to Apache, it would be easier just to do everything with node, so I'm guessing you don't want that

Here is a simple solution I found that works to add socket.io real-time interactivity to any existing html page, even when that page is hosted on another server.
Include a reference to socket.io in the head of the html page. The IP address and port number should be the location of your node.js server that is running socket.io.
<script src="http://xxx.xxx.xxx.xxx:xxxx/socket.io/socket.io.js"></script>
[NOTE: localhost doesn't work, you must use the actual IP address - don't forget the port]
Then, within a script block on the same html page, open a connection to the socket:
<script>
var socket = io.connect('http://xxx.xxx.xxx.xxx:xxxx');
</script>
That's it, you're connected!

Related

Tell Javascript code whether the App is running in remote host or localhost

I have a host name in javascript function and use Ajax to send JSON to server, I test it in localhost and I upload to remote host to test again.
Everytime I upload my web app to remote host and I need to manually change the host name to remote host name to test it,
localhost => mydomain.com
I have to change it back if I test it in my local machine.
mydomain.com => localhost
BTW, the font end is Javascript Html CSS, The backend is not Node.js and Not javascript. (It is Haskell)
I'm wondering how to tell my javascript code I'm running my App. in remote host or I'm running my App. in localhost so that my javascript can use different hostname in the code.
My current solution is I get the OS name in the backend code, and create
<div id='myid'>OS_Name</div>
and hide in my html page, and my javascript function read the 'id=myid' to get the OS_Name so my javascript code can distinct localhost or remote host.
I'm sure there better solution for this problem.
Can anyone have any suggestions?
You can use process.env.PUBLIC_URL to get the base url of where you app is running in node. So instead of constantly changing localhost to mydomain.com and back again, you can use process.env.PUBLIC_URL.

A question about how web applications work and how server-client is implemented

This is kind of a weird question I think to ask, but I have browsing about for the past some time and cannot find a clear definite answer.
I understand that a client connects to its own server and communicates with the web-server through sockets and I kind of see how that works in php (I have never used php but have used sockets before so I understand the concept).
The issue is I'm trying to get a real view of this.
The question is, do websites generally use sockets and contact a web-server to fetch data or the actual html? Or is it a rare choice made in some areas?
If it is generally used, then is the "real" js usually in the server? or is it client-side (for performance sake)?
Context:
Let me explain a bit where I'm coming from, I'm not a web expert, but I am a computer engineering student so most concepts are easy to understand. A "real"-er view of this would be very helpful.
Now, onto why I'm asking this. I'm developing a web-app as part of a project and have done a fair bit of progress on it but everything was done on a local dev server (so basically a client?)
I've started wondering about this because I wanted to use a database for my website and since I want to connect to something, I will need to connect to a web-server first (for security sake).
My question's intent is to guide me on how and most importantly, where, to setup this server.
I don't think showing any code would be of help here, but assume I have my client running on localhost:1234, my database on localhost:3306, I think I should have a web-server on another port so I can establish this communication, but I want to do it in a clean and legitimate way so all of my current solutions can be ported online with little to no changes (except the obvious)
There's a bunch to unpack here.
First of all, servers can be distant or local. Usually they are distant, local server are mostly used for development purposes.
Even if your server is on your local machine, it still isn't the client. The client is the part that is connecting to your server. For web development it is usually the user browser.
Javascript is a language that can be used server-side, with a NodeJS server, but more often client-side, in your user browser.
Your website, or web application, communicate with your server through various means. Most common one is the HTTP protocol, used to make server requests such as data request to populate your page (in case of an API server, REST or otherwise), or simply request the actual page to display in the browser. The HTTP protocol works by resolving URLs, and making requests to your server registered to this url using special methods such as GET, POST, DELETE, etc...
Sockets are used to create a persistent connection with your server that works both ways. It is mostly used for realtime updates, such as a live chat, as it allows you to push updates from the server instead of having the client request everything.
In most cases the database can be found on the same server as the one serving the website or application, as it is a lot easier to handle, and often faster without the extra networks requests to get the data. However it can be placed on another server, with it's own API to get the data (not necessarily web related)
Ports such as 1234 or 3306 are often used for local development, however once your move your project to a host service, this is usually replace by urls. And the host service will provide you with a config to access the associated database. Or if you are building your own server you might still use ports. It is heavily dependent on your server config.
Hope this clear some things up.
In addition to #Morphyish answer, in the simplest case, a web browser (the client) requests an URL from a server. The URL contains the domain name of the server and some parameters. The server responds with HTML code. The browser interprets the code and renders the webpage.
The browser and the server communicates using HTTP protocol. HTTP is stateless and closes the connection after each request.
The server can respond with static HTML, e.g. by serving a static HTML file. Or, by serving dynamic HTML. Serving dynamic HTML requires some kind of server language (e.g. nodejs, PHP, python) that essentially concatenates strings to build the HTML code. Usually, the HTML is created by filling templates with data from the database (e.g. MySQL, Postgres).
There are countless languages, frameworks, libraries that help to achieve this.
In addition to HTML, the server can also serve javascript that is interpreted in the browser and adds dynamics to the webpage. However, there could be 2 types of javascript that should not be mixed. NodeJS runs on the server and formats the server response, client javascript runs on the browser. Remember, client and server are completely isolated and can communicate only through an HTTP connection.
That said, there ways to make persistent connections between client and server with WebSockets, and add all kinds of exotic solutions. The core principle remains the same.
It does not matter if server software (e.g apache, nginx) is running on your local machine or anywhere else. The browser makes a request to an address, the DNS and network stack figures out how to reach the server and makes it work.

Is it possible to run a Node script from a web page?

I'am searching for days now but could not get an answer.
I would like to do the following:
User connects to editor.html (Apache2 with basic http auth)
User want to open a file (lets say /home/user1/myfile.txt) on the server with his user/pass (same as in passwd)
Node.js Script gets startet with user rights from above and user can edit file
The Node Script will handle the connection via websockets and read/writes files.
I think the biggest problem is that its not possible to run a node script on the server from a web page... and I don´t want to involve any php/cgi scripts... only Apache and Node.js / JS.
Please also comment or answer if you know that it is really not possible...
Thanks!
Kodak
Edit: The workflow should be the following:
User access webpage -> enters his credential (same as in passwd) -> node.js script gets started with the user rights of the logged in user -> files getting read or written with user rights
Biggest Problem: who starts the Node.js script? Apache? How?
I hate to be this person, but...
That is not the way node is designed, it is designed to use the event loop, I would recommend having node serve the static files, maybe using apache as a proxy, then when someone requests a certain page, doing what ever needs to be done, if you really must spawn a child process, use child_process.spawn, as for the rights of the user, I recommend just passing in a code, like 1=admin, 2=user, 3=guest, and the child process can do what is needs.
Use Socket.io - Official Socket.IO Website
You can also use Express with socket IO to create a separate app server. - Express JS Website
You may want to consider security implications of allowing a user to connect directly using their server side account. There are also many applications available that already do this that you might consider implementing instead of writing your own, with all the properly embedded security that will be required.
Let your users GET static auth.html page (via apache) without any authentication.
Let form submit action is some auth.js (Node.js script). This auth.js check if user's authentication is success. If so it starts node.js server, setups socket.io on it and redirects user to some editor.html.
In this case as you can notice that there is an authentication based on node.js scripting. If you want basic apache2 one I can recommend you the next scenario:
There is auth.html and editor.html pages on the server. Last one placed in /private folder and direct access to this folder is denied by .htaccess. So when the user pass apache2 authentication in auth.html he GET this auth.html which is empty document with onload event handler that send AJAX to auth.js (Node.js script). Node.js get private/editor.html and send it to user like /editor.html.
In this case user never has an access to editor without passing authentication. And after authentication node.js server is started and socket.io is setup and everything fine.
I found a solution:
It is possible to write a custom authentication program for apache with mod-auth-external:
https://code.google.com/p/mod-auth-external/
With basic authentication enabled the webserver would pass the credentials to a script/program and this can then run the node app.

Client-side socket.io without a node.js server

To use socket.io on the client side, usually we start a node.js server and go like this:
<script src="/socket.io/socket.io.js"></script>
or with specific port:
<script src="http://localhost:3700/socket.io/socket.io.js"></script>
Question is:
is it necessary to use node.js server to serve socket.io.js ?
...or is it possible to
make a local copy of socket.io.js instead of goes to server every single time we need socket.io?
like, we go to view source and copy everything we got from the source of script tag,
paste and save it as socket.io-local.js so that next time we use:
<script src="socket.io-local.js"></script>
will that work ?
Updates
Thanks for everyone's great response,
I'm asking this because in the case I'm involved, I don't actually have access to the server:
I am writing the client-side to connect to other developer's Socket Sever which is written in Java.
Therefore I'll have to think a way to work around the fact that I don't have a server there for me.
from what I've been testing,
this way seems to work but I really don't know what's happening behind the scene.
You obviously can host the socket.io client library anywhere and pull it in to a page. However, it will almost certainly not work with your Java-based server.
To understand why, you need to understand what socket.io is really doing behind the scenes; the client library is only a small part of it.
Socket.io actually defines and implements its own protocol for realtime communication between a browser and a server. It does so in a way that supports multiple transports: if—for example—a user's browser or proxy doesn't support WebSockets, it can fall back to long polling.
What the socket.io client actually does is:
Makes a XHR GET request for /socket.io/1. The server responds with a session ID, configured timeouts, and supported transports.
The client chooses the best transport that the user browser supports. In modern browsers, it will use WebSockets.
If WebSockets are supported, it creates a new WebSocket to initiate a WebSocket connection (HTTP GET with Upgrade: websocket header) to a special URL – /socket.io/1/websocket/<session id>.
If WebSockets aren't supported by the browser or fail to connect (there are lots of intermediaries in the wild like proxies, filters, network security devices, and so forth that don't support WebSocket requests), the library falls back to XHR long polling, and makes a XHR request to /socket.io/1/xhr-polling/<sesion id>. The server does not respond to the request until a new message is available or a timeout is reached, at which point the client repeats the XHR request.
Socket.io's server component handles the other end of that mess. It handles all the URLs under /socket.io/, setting up sessions, parsing WebSocket upgrades, actually sending messages, and a bunch of other bookkeeping.
Without all of the services provided by the socket.io server, the client library is pretty useless. It will just make a XHR request to a URL that doesn't exist on your server.
My guess is that your Java-based server just implements the WebSockets protocol. You can connect directly to it using the browser-provided WebSocket APIs.
It is possible that your server does implement the socket.io protocol – there are a few abandoned Java projects to do that – but that's unlikely. Talk with the developer of your server to find out exactly how he's implemented a "socket server."
A standalone build of socket.io-client is exposed automatically by the socket.io server as /socket.io/socket.io.js. Alternatively you can serve the file socket.io-client.js found at the root of this repository.
https://github.com/LearnBoost/socket.io-client
I have a module called shotgun-client that actually wraps socket.io. I needed to serve a custom client script as well as the socket.io client script, but I didn't want every user of my module to have to include multiple script references on their pages.
I found that, when installed, you can serve the generated client script from socket.io by reading the file /node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js. So my module adds a listener for its own URL and when it serves my custom client script it also serves the socket.io client script with it. Viola! Only a single script reference for the users of my module :)
While this is technically possible, I don't see why you'd need to do that. If you're concerned about reducing the data that goes over the wire, this change won't actually do much beyond the few characters saved in the shorter src tag. Simply changing the location of the JS file on the server won't actually improve performance - the JS has to be sent.
Proper caching (which Socket.IO has) will return a 304 Not Modified (and not re-send the JS file every time you load a page).

How to solve JavaScript origin problem with an application and static file server

In a system that I'm building I want to serve
Static files (static HTML pages and a lot of images), and
Dynamic XML generated by my servlet.
The dynamic XML is generated from my database (through Hibernate) and I use Restlets to serve it in response to API calls. I want to create a static file server (e.g. Apache) so that this does not interfere with the dynamic server traffic. Currently both servers need to run on the same machine.
I've never done something like this before and this is where I'm stuck:
The static HTML pages contain JavaScript that makes API calls to the dynamic server. However, since the two servers operate on different ports, I get stuck with the same origin problem. How can this be solved?
As a bonus, if you can point me to any resources that explain how to create such a static/dynamic content serving system, I'll be happy.
Thanks!
You should setup mod_proxy in apache to forward dynamic requests to whatever backend server you are using. Your existing setup (ie. two separate ports) is perfect, you just need to tell apache 'proxy dynamic requests to my backend server without letting the browser know'.
This page should get you started - http://httpd.apache.org/docs/1.3/mod/mod_proxy.html
You need to load a script tag from the Reslet server... have a look at JSONP and this SO post

Categories