User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Websocket with NGINX and jquery on my webpage

Sun Oct 02, 2016 1:15 pm

Hello everyone,
if someone tried to use WebSocket on NGINX server with Python socket server script for starting WS server and jquery on the website and in what way? I started connecting via WebSocket so if anyone has some simple example?

Thank you,
Faramon
Last edited by faramon on Sun Oct 02, 2016 2:04 pm, edited 1 time in total.

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Sun Oct 02, 2016 1:46 pm

You thread title says "nginx". Your question says "Apache"

Which is it?

Anyway forget about Apache, nginx, PHP, Python. You can do all this far more easily in Javascript running under node.js.

With node.js you can create a web server very easily and that web server can also be a websocket server. That same program can read/write GPIO, serial ports, database, whatever you like.

I have a very short a sweet example of such a node.js websocket server here:
https://bitbucket.org/zicog/pigpio2html/overview

That does not use jQuery. Just plain HTML and Javascript. But then I would not use jQuery either. Much nicer to do your client side GUI updating with React.js
https://facebook.github.io/react/

If you then want to use nginx or Apache it is very easy to get nginx to forward incoming requests to Apache and your node.js server(s).
Memory in C++ is a leaky abstraction .

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Sun Oct 02, 2016 1:55 pm

Heater wrote:You thread title says "nginx". Your question says "Apache"
Sorry, i try to search from google and my clipboard is used word Apach when i Paste it on the forum.
It is NGINX.

Faramon

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Sun Oct 02, 2016 2:02 pm

If you are using nginx it will be listening on the normal HTTP port, 80, or the HTTPS port, 443.

Your node.js server will therefore have to be listening on some other port number. Say 4000.

It is very easy to get nginx to forward requests to your node.js server(s) with some simple configuration. See here for a nice article about that:
https://gist.github.com/soheilhy/8b94347ff8336d971ad0
Memory in C++ is a leaky abstraction .

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Sun Oct 02, 2016 2:16 pm

Thanx,
i will read those links.

Faramon

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Mon Oct 03, 2016 3:08 pm

I found simple example. It contains html with javascript socket connection and server.py script.
This works when server.py is started and I have uploaded html to NGINX web server and when javascript send ws request, Python receive connection but it cannot send something back. I try on many ways but i do not receive ws response from Python server script. Ideas?
I have noip dyndns domain and port forvard on my router but unsucessfully.
HTml receive error in console log in firefox: "The connection was refused when attempting to connect to ws://mysite.ddns.net:12345/.

My html and server.py:

Code: Select all

<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
  function init(evt) {
	document.myform.url.value = "ws://mysite.ddns.net:12345/"
	document.myform.inputtext.value = "Hi!"
	document.myform.disconnectButton.disabled = true;
  }

  function doConnect() {
    websocket = new WebSocket(document.myform.url.value);
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
  }

  function onOpen(evt) {
    writeToScreen("connected\n");
		document.myform.connectButton.disabled = true;
		document.myform.disconnectButton.disabled = false;
  }

  function onClose(evt){
    writeToScreen("disconnected\n");
		document.myform.connectButton.disabled = false;
		document.myform.disconnectButton.disabled = true;
  }

  function onMessage(evt) {
    writeToScreen("response: " + evt.data + '\n');
  }

  function onError(evt){
    writeToScreen('error: ' + evt.data + '\n');
	websocket.close();
	document.myform.connectButton.disabled = false;
	document.myform.disconnectButton.disabled = true;
  }

  function doSend(message){
    writeToScreen("sent: " + message + '\n'); 
    websocket.send(message);
  }

  function writeToScreen(message){
    document.myform.outputtext.value += message
	document.myform.outputtext.scrollTop = document.myform.outputtext.scrollHeight;

  }

  window.addEventListener("load", init, false);

   function sendText() {
	doSend( document.myform.inputtext.value );
   }

  function clearText() {
		document.myform.outputtext.value = "";
   }

   function doDisconnect() {
		websocket.close();
   }

</script>

<div id="output"></div>

<form name="myform">
	<p>
	<textarea name="outputtext" rows="20" cols="50"></textarea>
	</p>
	<p>
	<textarea name="inputtext" cols="50"></textarea>
	</p>
	<p>
	<textarea name="url" cols="50"></textarea>
	</p>
	<p>
	<input type="button" name=sendButton value="Send" onClick="sendText();">
	<input type="button" name=clearButton value="Clear" onClick="clearText();">
	<input type="button" name=disconnectButton value="Disconnect" onClick="doDisconnect();">
	<input type="button" name=connectButton value="Connect" onClick="doConnect();">
	</p>
</form>
</html> 

Code: Select all

#!/usr/bin/python

import socket

s = socket.socket()
#host = socket.gethostname()
port = 12345
#s.bind((host,port))
s.bind(('',port))

s.listen(5)
while True:
    c, addr = s.accept()
    print 'Got connection from', addr
    c.send('Thank you for connecting')
    c.close()
Attachments
py.PNG
py.PNG (29.8 KiB) Viewed 4005 times

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Mon Oct 03, 2016 6:40 pm

faramon,

I'm pretty sure what you are trying there cannot possibly work.

Your web page tries to open a websocket connection to your Python server.

But your Python server is only a regular TCP/IP socket server. Not a websocket server. I know nothing of Python much but assume that is all the socket module that you are importing does,

A web socket is a kind of HTTP connection. Rather than the normal HTTP "request and response then close the connection" of web page loading, a websocket connection involves making an HTTP request to a web server. Then telling the web server to keep that connection open for future data exchange.

Your Python socket server gets a connection from the web browser, but it does nothing to handle the HTTP request the browser sends over that connection or the upgrading of the HTTP connection to a websocket connection.

I could not resist playing with your code. I made a few modifications...

First the HTML. I changed it to use the socket.io library to handle web socket connections. This makes life easier because socket.io handles all the opening of the websocket, error checking, it will reconnect if the connection fails. socket.io can create many "channels" over the web socket connection if you have different streams of data going on. It has a lot of useful features.

I removed the connect and disconnect buttons as they are not needed. If you really need them socket.io has interfaces for that as well.

As you see the code is now very short:

Code: Select all

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>WebSocket Test</title>
        <script src="/socket.io/socket.io.js"></script>
    </head>
    <body>
        <form name="myform">
            <p>
                <textarea name="outputtext" rows="20" cols="50"></textarea>
            </p>
            <p>
                <textarea name="inputtext" cols="50"></textarea>
            </p>
            <p>
                <input type="button" name=sendButton value="Send" onClick="sendText();">
                <input type="button" name=clearButton value="Clear" onClick="clearText();">
            </p>
        </form>
        <script>
            var socket = io();  // This will make a web socket connection to the server of this page
            // var socket = io('http://somehost/somePath');  // Or supply a different URL for the web socket server.
            socket.on('myMessage', function (data) {
                writeToScreen("response: " + data.content + '\n');
            });

            document.myform.inputtext.value = "Hi!"

            function writeToScreen(message){
                document.myform.outputtext.value += message
                document.myform.outputtext.scrollTop = document.myform.outputtext.scrollHeight;
            }

            function clearText() {
                document.myform.outputtext.value = "";
            }

            function sendText() {
                var message = document.myform.inputtext.value;  
                writeToScreen("sent: " + message + '\n'); 
                socket.emit('myMessage', { content: message });
            }
        </script>
    </body>
</html> 
Then the server. I wrote a new server in Javascript to run under node.js. It's much easier to do web server and web socket things in node.js. No NGINX or Apache required.

This server uses the Express node.js module to create the web server. Attaches the socket.io module to that to handle web sockets. It just serves up the HTML and listens for websocket connections back from it. It just echos whatever data is received on the websocket.

The code for the complete web and websocket server is also very short.

Code: Select all

'use strict';

// Change process name so we don't see it as just "node" in ps and top
process.title = 'server';

// ------------------------- Web Server ----------------------------------------

const PORT = 4000;

// Use express as our web app server
let express = require('express');
const app = express();

let http = require('http');
const server =  http.Server(app);

// Use morgan for logging requests
let morgan = require('morgan');
app.use(morgan('dev'));

// Make an express `Router`.
var router = express.Router();

// Serve static content from the public subdirectory
const publicPath = '.';
console.log('Serving static content from:', publicPath);
let serveStatic = require('serve-static');
router.use(serveStatic(publicPath));

// Now we can tell the app to use our router:
app.use('/', router);

// Start the server listening for requests.
server.listen(PORT, function() {
    console.log(`Listening for http requests on port ${PORT}`);
});

// ------------------------ websocket server ----------------------------------

let socketio = require('socket.io');
const sio = socketio(server);

sio.on('connection', function (socket) {
    console.log("Web socket client connected");
    socket.on('myMessage', function (data) {
        let message = data.content;
        console.log(data);
        socket.emit('myMessage', { content: message });
    });
});

To run this you just need to install node.js. Use NVM to do that: https://github.com/creationix/nvm

Then create a package.json file in the same directory as the html and server.js. Like so:

Code: Select all

{
  "name": "faramon",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.14.0",
    "morgan": "^1.7.0",
    "socket.io": "^1.4.8"
  }
}
This makes install the required modules easy with:

Code: Select all

$ npm install
Then run the thing as:

Code: Select all

$ node server.js
And point your browser at localhost:4000
Memory in C++ is a leaky abstraction .

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Tue Oct 04, 2016 5:43 am

Hi Heater,
thank you so much for all the hard work that you've written, surely I will immediately move in this direction.

When I create socket sucessfully, I'll write my impressions.

Faramon

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Tue Oct 04, 2016 6:14 am

Not so much hard work. I just copy and pasted most of that from other projects.

Good luck, look forward to hearing how you get on.
Memory in C++ is a leaky abstraction .

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 10:31 am

Hi,
I found that my Node version is v0.10.29. Is this version good or I have to install new version of Node for doing websocket stuff?

Thanx,
Faramon

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 11:12 am

v0.10.29 can do websocket stuff.

But I seriously suggest you get a recent version of node.js. node has progressed a lot since then. It's got faster. it supports the new language features that come with the 2015 version of Javascript standard. It is possible that APIs have changed such that new node.js modules won't run on old node.js.

The simplest way to get a new node installed is this:

1) Install the node version manager, nvm:

Code: Select all

$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.0/install.sh | bash
or

Code: Select all

$ wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.32.0/install.sh | bash  
2) Use nvm to install node.js:

Code: Select all

$ nvm install node
3) Take it into use:

Code: Select all

$ nvm use node
After that it is very easy to upgrade to new versions of node as they come along. See nvm instruction here: https://github.com/creationix/nvm
Memory in C++ is a leaky abstraction .

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 11:34 am

Ok, I have to ask because I read somewhere that if I do not uninstall node, the new one need to be set as default...
Is this correct?
Thanx,
Faramon

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 11:47 am

You don't have to uninstall the old node.

After you have installed a new node with nvm you can list all the versions of node you have installed like so:

Code: Select all

$ nvm   ls
       v0.10.26  
       v0.10.32  
       v0.11.14  
->       v6.4.0  
         system  
default -> 6.4.0 (-> v6.4.0)
node -> stable (-> v6.4.0) (default)
stable -> 6.4 (-> v6.4.0) (default)
You can use your operating systems old node if you want:

Code: Select all

$ nvm use system
Now using system version of io.js: v2.4.0
And switch back to using your new one:

Code: Select all

$ nvm use stable
Now using node v6.4.0 (npm v3.10.3)
You can change the default version of node used when you start a new shell:

Code: Select all

$ nvm alias default node
default -> node (-> v6.4.0)
It's all in instructions I linked to above.
Memory in C++ is a leaky abstraction .

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 1:09 pm

Great,

I follow your instructions and i get new node v6.7.0 installed, thanx.

Now, i go to do other stuff you have written about (HTML and JS)...
when I do this, I will inform the progress...

Faramon

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 2:23 pm

Excellent.

All the best.
Memory in C++ is a leaky abstraction .

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 4:24 pm

Hi,
I spent more than 2 hours to get it works but unsuccessfully.
I also try npm run build, npm start, and I do not remember what else I try but nothing works...
node /var/www/html/socket/server.js not work, It gives me a error on picture.
What can I do else?

Thanx,
Faramon
Attachments
rpi.jpg
rpi.jpg (57.66 KiB) Viewed 3523 times

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 6:33 pm

Ah I see.

As the error message says, "Cannot find module 'express'"

Let's start from the beginning. Let's say you want to create a new node.js program, an HTTP server that uses the express module. This is what you should do:

1) Create a directory for your new program and change into it:

Code: Select all

$ mkdir myProg
$ cd myprog
2) Create a package.json file for your program. This file will end up describing your program, it's version number, the modules it depends on and other things. The quickest way to create this file is:

Code: Select all

$ npm init
And answer the questions it asks. This will create a simple package.json file.

3) Install any modules you will be using. With npm of course. But use the --save option:

Code: Select all

$ npm install express --save
This will install the express module into the node_modules directory inside your project and record the module dependency in the package.json file

4) Now write your code. server.js or whatever it is called.

Now when you want to run your program just make sure you are in the projects directory and get node to run it:

Code: Select all

$ cd /where/ever/myProg
$ node server.js
This all sounds long winded but it is quicker to do than say and is very convenient in the future.

For example if you copy your code elsewhere, or give a copy to me, or put it in github, you don't need to include the node_modules directory in the copy or repository.

Instead, you just change to the directory containing the copy, get npm to install all the required modules, and run it:

Code: Select all

$ cd where/ever/myProg
$ npm install
$ node server.js
So, back to your case. Is that one of my examples you are running? Which one? I suspect changing to the directory where you have put it and using "npm install", "npm run build", "node server.js" should get it working.

Hope that helps.
Memory in C++ is a leaky abstraction .

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 7:02 pm

Ho ho ho,
youre steps make my day...
I am in...
Listening for http requests on port 9009 (this is my port)...
Great...
Thanx, thanx, thanx....
Because I'am new to Raspbian, I learn step by step, day by day...

I go further to set html to work with node.js websocket...

Thanx,
Faramon

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 7:08 pm

... And, I get response to html from websocket.
This is awesome!!!
Heater, you are awesome, you rule.
Thanx, thanx... and very nice tutorial you gave me.

Faramon

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 7:37 pm

faramon,
Heater, you are awesome, you rule.
Wow, thanks.

But it's not me. It's Brendan Eich who created Javascript, Ryan Dahl who created node.js and the thousands of people who have worked on it since.

I'm just keen to spread the word.

Sadly it's all harder to get started with than it should be because node.js is not packaged up nicely with the operating system like other languages.

Well done.
Memory in C++ is a leaky abstraction .

User avatar
faramon
Posts: 123
Joined: Sat Jun 11, 2016 8:36 am
Location: Croatia

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 7:48 pm

Of course,
almost all thanks go to them (98%), they are the creators of these things.
For you, I told you are awesome as you have written excellent instructions on using this pices of code and sent me that I get the right thing.
My knowledge of Linux is almost zero because I come from a windows environment.

Thanx,
Faramon

Heater
Posts: 15949
Joined: Tue Jul 17, 2012 3:02 pm

Re: Websocket with NGINX and jquery on my webpage

Wed Oct 05, 2016 7:57 pm

The good news is that node.js and pretty much everything I have talked about here works on Windows as well. Recently I have been developing node programs on Windows quite a bit.

I'm not sure but I think there is no nvm for windows so you may have to get node for windows directly from nodejs.org https://nodejs.org
Memory in C++ is a leaky abstraction .

Return to “General discussion”