i'm newbie in nodeJS, after successfully installing socket.io by npm command i'm create simple js as this code:
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs');
function handler( request, response ) {
fs.readFileSync( __dirname + '/index.html', function( error, data ) {
if( error ) throw error;
response.writeHead(200);
response.end( data );
});
};
app.listen( 1377 )
io.sockets.on( 'connection', function( socket ) {
socket.on( 'loginRequest', function( data ) {
login( data );
});
});
function login( data, socket) {
return socket.emit('loginAnswer', true)
};
this file can be run correctly by node application.js without any problem, now i'm create simple html code:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.3.4.js"></script>
<script>
var socket = io('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
</head>
<body>
<form onsubmit='requestLogin()'>
<input id='username' type='text'>
<input id='password' type='password'>
<input type='submit'>
</form>
</body>
</html>
name of this file is index.html, i'm using xampp and both of files are in htdocs root, htdocs is only have this files, now i'm open localhost:1337 in browser and i get error
after change address to localhost:1337 i get this error:
Unable to connect
Firefox can't establish a connection to the server at localhost:1337.
You use fs.readFileSync where you should use fs.readFile,
also realizing that you listen to port 1377, and try to use port 1337,
in index.html add the port to the socket connection io('http://localhost:1377');
Related
I am new to this area so forgive me if I fail to explain my question well.
I am essentially trying to send a string "Hello, I connected to the port" to my Javascript client, only when I have pressed a HTML button.
FOR TESTING PURPOSES:
I have been successful in running a client and server Javascript socket connection, and can receive data back and forth. However when trying to link this to my html page I fail to connect them and send data.
CLIENT.JS:
const net = require('net');
const client = net.createConnection({ port: 9898 }, () => {
console.log('CLIENT: I connected');
client.write('CLIENT: Hello this is client!');
});
client.on('data', (data) => {
console.log(data.toString());
client.end();
});
client.on('end', () => {
console.log('CLIENT: I disconnected from the server.');
});
SERVER.JS
const net = require('net');
const server = net.createServer((socket) => {
socket.on('data', (data) => {
console.log(data.toString());
});
socket.write('SERVER: Hello! \n');
socket.end('SERVER: Closing connection now \n');
}).on('error', (err) => {
console.error(err);
});
server.listen(9898, () => {
console.log('opened server on', server.address().port);
});
if you save the above code and run them using the lines:
node server.js
node client.js
You will find that they send messages between them quite nicely.
The issue starts when I try to run my html page (which is served using node.JS on port 8083)
(I server my HTML page using npx http-server --cors)
An approach I tried was to place the code in client.js into a function and then call it in my html button:
<input type = "button" onclick = "outputData()" value = "Display">
(outputData being the function that contains the code in client server)
I'm not sure if its even something that can be done, but I'd like to essentially start my server.js from my HTML page, when a button is clicked, so that it can begin sending the data. I'd want to run "node client.js" on terminal and see that messages are coming through as server.js would have been started from my webpage
Any advice would be highly appreciated. Thank you for taking the time.
Information about socket.io library, https://socket.io/docs/v3/client-api/index.html
Sending message index.html
<html>
<body>
<input type="button" onclick="javascript:sendMessage()" value="Click here"/>
<script>
const sendMessage = () => {
var new_message = {message: "this is my message"}
socket.emit('new_message', new_message);
}
</script>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io("http://localhost:8080");
</script>
</body>
</html>
server.js
socket.on('new_message', (data) => {
var New_Details = {
message: data.message
};
socket.broadcast.emit('update_message', New_Details);
console.log(data.username + ' just wrote ' + data.message);
});
I managed to solve this by using Websockets. Where my webserver acted as the client, and I adjusted my server.js to the following:
SERVER.JS
const WebSocket = require("ws");
const wss = new WebSocket.Server({ port: 9898 });
wss.on("connection", ws => {
console.log("New client connected!");
ws.on("message", data => {
console.log(`Client has sent us: ${data}`);
ws.send(data.toUpperCase());
});
ws.on("close", () => {
console.log("Client has disconnected!");
});
});
HTML
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/assets/dcode.css">
<link rel="shortcut icon" href="/assets/favicon.ico" type="image/x-icon">
<title>WebSockets</title>
</head>
<body>
<script>
const ws = new WebSocket("ws://localhost:9898");
ws.addEventListener("open", () => {
console.log("We are connected!");
ws.send("Hey, how's it going?");
});
ws.addEventListener("message", ({ data }) => {
console.log(data);
});
</script>
</body>
</html>
I've been through A LOT of issues in here about this topic but so far no answers has been the solution for my problem.
My setup is an AWS EC2 server with apache installed. I've installed node.js in the /node folder containing a server-file called server.js and in the root folder I have my client-file index.php. I have Let´s Encrypt SSL-certificates for my domain and therefore I need everything to run over https. I have opened up the port 3000 for all traffic en AWS.
Server.js
const app = require('express')();
const fs = require('fs');
const options = {
key: fs.readFileSync("/etc/letsencrypt/live/example.com/privkey.pem"),
cert: fs.readFileSync("/etc/letsencrypt/live/example.com/fullchain.pem")
};
const http = require('https').Server(options, app);
const io = require('socket.io')(http);
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
console.log('message: ' + msg);
});
});
http.listen(3000, function(){
console.log('listening on 3000');
});
index.php
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Socket Test</title>
</head>
<body>
<ul id="events"></ul>
<script src="https://cdn.jsdelivr.net/npm/socket.io-client#2/dist/socket.io.js"></script>
<script>
const events = document.getElementById('events');
const newItem = (content) => {
const item = document.createElement('li');
item.innerText = content;
return item;
};
const socket = io('https://example.com:3000', {transports: ['websocket', 'polling']});
console.log(socket);
socket.on('connect', () => {
console.log("did connect");
events.appendChild(newItem('connect'));
});
socket.on('disconnect', () => {
console.log("did disconnect");
});
</script>
</body>
</html>
The problem
When I start my node server everything seems right. Executing node server.js returns listening on 3000 as supposed. When I go to index.php it never returns did connect BUT when I then exit the server node I get the did disconnect message in the browser console.
Also the server never returns anything else but listening on 3000.
Please help me :-)
Since the recent update to v3.0.0, version 2.x.x clients are not compatible so won't be able to connect.
The fix is to make sure both client and server are using the same versions, or use the server served version /socket.io/socket.io.js (which is not always possible, webpack etc)
Related issue on github: https://github.com/socketio/socket.io-client/issues/1390
I am running a local website with NodeJS on my Pi and I want to control a lamp via an 433MHz sender connected to the Pi. I have already written a bash script which works perfectly to control the lamp but I can't find a way to execute it through the HTML site on the node server.
So I am asking whether it is even possible because it doesn't really seem secure to me and how can I implement it in javascript as a function or only on the server side ?
there are many ways you could go about doing something like this but one way would be creating an api so your website can make api calls to the server to turn the light on and off
so here is a simple example
HTML
<html>
<head>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
</head>
<body>
<form>
<input type="button" Value="on" onclick="turnOn()">
<input type="button" value="off" onclick="turnOff()">
</form>
</body>
</html>
<script>
function turnOn(){
$.ajax({
url: 'http://localhost:3000/api/light/on',
type: "GET",
dataType: "json",
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(`Error ${error}`);
}
});
}
function turnOff(){
$.ajax({
url: 'http://localhost:3000/api/light/off',
type: "GET",
dataType: "json",
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(`Error ${error}`);
}
});
}
</script>
SERVER
//server.js
const app = require('express')();
const server = require('http').createServer(app);
var cors = require('cors');
const shell = require('shelljs')
var port = 3000;
server.listen(port, () => console.log(`API server running on ${port}!`))
app.use(cors())
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
})
app.get('/api/light/:status', (req, res) => {
var status = req.param('status')
if(status == 'on'){
shell.exec('./turn-light-on')
res.json({success:"light turned on"})
}else{
shell.exec('./turn-light-off')
res.json({success:"light turned off"})
}
})
all you would have to do is change the file that shell.exec() calls for it to work
this app reqires
express
cors
shelljs
to be installed just npm install the names as listed above
When the client connects to the server a message is supposed to be emitted to the console. I'm not getting any errors so I'm confused as to what my problem actually is.
Server: As you can see the client connects.
Client: The message doesn't appear in the console.
(Forgive me for the links, I don't have 10 reputation)
How do I get the message to print to the console?
I've read other posts like this one, but they weren't helpful :(
When you do io.connect(), that call is asynchronous and not immediate. You cannot immediately emit to the server until the client generates the connect event:
var socket = io.connect()
socket.on('connect', function() {
// it is safe to call `.emit()` here
socket.emit("sndMsg", someData);
});
index.html
<html>
<head>
<script src='/socket.io/socket.io.js'></script>
<script>
var socket = io();
socket.on('welcome', function(data) {
addMessage(data.message);
// Respond with a message including this clients' id sent from the server
socket.emit('i am client', {data: 'foo!', id: data.id});
});
socket.on('time', function(data) {
addMessage(data.time);
});
socket.on('error', console.error.bind(console));
socket.on('message', console.log.bind(console));
function addMessage(message) {
var text = document.createTextNode(message),
el = document.createElement('li'),
messages = document.getElementById('messages');
el.appendChild(text);
messages.appendChild(el);
}
</script>
</head>
<body>
<ul id='messages'></ul>
</body>
</html>
server.js
var http = require('http'),
fs = require('fs'),
// NEVER use a Sync function except at start-up!
index = fs.readFileSync(__dirname + '/index.html');
// Send index.html to all requests
var app = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(index);
});
// Socket.io server listens to our app
var io = require('socket.io').listen(app);
// Send current time to all connected clients
function sendTime() {
io.emit('time', { time: new Date().toJSON() });
}
// Send current time every 10 secs
setInterval(sendTime, 10000);
// Emit welcome message on connection
io.on('connection', function(socket) {
// Use socket to communicate with this particular client only, sending it it's own id
socket.emit('welcome', { message: 'Welcome!', id: socket.id });
socket.on('i am client', console.log);
});
app.listen(3000);
I posted the code for my index.html, app.js and insert.php.
The dependencies installed are express, mysql and morgan.
In my folder I have
/node_modules
app.js
index.html
insert.php
package.json
I have a WAMP local server running in the background. phpMyadmin's username is root and password is blank, by default. I've set up a database called storestuff with a table in it named thestuff which has two columns title and content.
So I run node app.js in the terminal and then get
Server running on port 3000.
Connected successfully to the database.
Now, I go to visit localhost:3000
When the page loads, terminal shows GET / 304 20.635 ms - - which means the page loaded correctly.
I've also inserted some dummy data into the MySQL storestuff database using phpMyAdmin for testing purposes. Visiting localhost:3000/load which is a route set up in app.js, terminal shows GET /load 200 16.382 ms - -
which shows in the browser, a page with JSON data which is indeed the dummy data I had inserted and http code 200 means the GET request worked properly.
When I fill out the title field and the content field and press submit, terminal shows POST /insert.php 404 2.949 ms - 150 which I don't understand because insert.php is in the same folder as index.html.
index.html
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro">
</head>
<body>
<font face="Source Sans Pro">
<div ng-app="myApp" ng-controller="myController">
<h1> Hello world! </h1>
<form>
Title <input type="text" ng-model="title"><br>
Content <input type="text" ng-model="content"><br>
<input type="button" value="Submit" ng-click="insertdata()">
</form>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function($scope, $http) {
$scope.insertdata = function() {
$http.post('insert.php', {
'title':$scope.title,
'content':$scope.content
})
.then(function(data) {
console.log("Data inserted into the MySQL database successfully.");
});
}
});
</script>
</div>
</font>
</body>
</html>
app.js
var express = require('express');
var mysql = require('mysql');
var morgan = require('morgan');
var app = express();
app.use(morgan('dev'));
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'storestuff'
});
connection.connect(function(error) {
if(error) console.log("Problem connecting to MySQL: " + error);
else console.log("Connected successfully to the database");
});
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
app.get('/load', function(req, res) {
connection.query("SELECT * from thestuff", function(err, rows) {
if(err) console.log("SELECT from thestuff... did not work: " + err);
else res.end(JSON.stringify(rows));
});
});
app.listen(3000, function() {
console.log("Server running on port 3000.");
});
insert.php
<?php
$data = json.decode(file_get_content('php://input'));
$title = mysql_real_escape_string($data->title);
$content = mysql_real_escape_string($data->content);
mysql_connect('localhost', 'root', '');
mysql_select_db('storestuff');
mysql_query("INSERT INTO thestuff('title', 'content') VALUES('".$title"', '".$content"')");
?>
add this in the top of your php file
<?php
header("Access-Control-Allow-Origin: *");
try with headers property
$http({
method: 'POST',
url: 'insert.php',
data: {'whetever':'data', 'in':'json format'},
headers: {'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'}
})
.then(function(res){
console.log('successful response', res);
.catch(function(err) {
console.error('Error while post', err);
});
and you can access in on insert.php
header("Access-Control-Allow-Origin: *");
if ($_SERVER['REQUEST_METHOD'] == 'POST' && empty($_POST)) {
$_POST = json_decode(file_get_contents('php://input'), true);
echo $data->whatever;
}
Note: you can also you set it globally for all post request within .config block as below
myApp.config(function($httpProvider) {
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});
You are using node to power your web server. Couple of things: in your app routes you don't have a route for app.post ('/insert.php'), which is the cause of your 404. But node.js itself won't interpret php files for you, so at best it will show the code for the php file. There are plugins you can use or use another web server like nginx in front of the express/nodejs.