So I'm trying to host a web app using node.js express and my server.js seems to hang upon using npm start. In my package.json file it calls node server.js and everything starts properly but my website won't deploy to the local host for me to view. I have a feeling it is either something to do with the location of my css/index.html or it could be something with the way i create the request from the client side from index.html I'm new to backend, so really out in the deep on this one.
//1.) create http server
const PORT = process.env.PORT || 2525;
const INDEX = '/public/index.html';
const express = require('express')
var server = express();
console.log(__dirname)
server.use(express.static(__dirname + "/public"));
server.get('public/index.html', function(req, res, next) {
res.sendFile(__dirname + INDEX);
});
server.listen(PORT);
//2.) Create a websocket server
const { Server } = require('ws');
const wss = new Server({ server });
//3.) Handle connections
wss.on('connection', (ws) => {
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
});
//4.) Boradcast updates
setInterval(() => {
wss.clients.forEach((client) => {
client.send(new Date().toTimeString());
});
}, 1000);
console.log('Server started at http://localhost:' + PORT);
This is my index.html below
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>am i sheep</title>
<link rel="stylesheet" href="css/style.css" type="text/css">
</head>
<body>
<div>
<span>
<h3> Am I Sheep<h3>
</span>
</div>
<div>
</div>
<div>
<input type="file" id="fileID" hidden></input>
<label for='fileID'>select image</label>
</div>
<div>
<h1 id='server-time'>current time</h1>
<script>
var HOST = location.origin.replace(/^http/, 'ws')
var ws = new WebSocket(HOST);
var el;
ws.onmessage = function (event) {
el = document.getElementById('server-time');
el.innerHTML = 'Server time: ' + event.data;
};
</script>
</div>
</body>
</html>
UPDATE:
So the issue that seems to be popping up now is
WebSocket connection to 'ws://localhost:2525/' failed
var ws = new WebSocket(HOST);
So the error is happening between the handshake between the client and server
The server.js
//1.) create http server
const PORT = process.env.PORT || 2525;
const INDEX = "/public/index.html";
const express = require("express");
const { createServer } = require("http");
const app = express();
const httpServer = createServer(app);
// Static files
app.use(express.static(__dirname + "/public"));
app.get("/", function (req, res, next) {
res.sendFile(__dirname + INDEX);
});
//2.) Create a websocket server
const { Server } = require("ws");
const wss = new Server({ server: httpServer });
//3.) Handle connections
wss.on("connection", ws => {
console.log("Client connected");
ws.on("close", () => console.log("Client disconnected"));
});
//4.) Boradcast updates
setInterval(() => {
wss.clients.forEach(client => {
client.send(new Date().toTimeString());
});
}, 1000);
httpServer.listen(PORT, () => console.log("Server started at http://localhost:" + PORT));
The index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>am i sheep</title>
<link rel="stylesheet" href="css/style.css" type="text/css">
</head>
<body>
<div>
<span>
<h3> Am I Sheep<h3>
</span>
</div>
<div>
</div>
<div>
<input type="file" id="fileID" hidden></input>
<label for='fileID'>select image</label>
</div>
<div>
<h1 id='server-time'>current time</h1>
<script>
var HOST = location.origin.replace(/^http/, 'ws')
var ws = new WebSocket(HOST);
var el;
ws.onopen = function () {
alert('Connection Open');
};
ws.onerror = function (error) {
alert('Error');
};
ws.onmessage = function (event) {
el = document.getElementById('server-time');
el.innerHTML = 'Server time: ' + event.data;
};
</script>
</div>
</body>
</html>
Related
I'm learning the socket.io library in Node.js and I can't make the server receive data, only send. During tests I noticed that the io.on listener function isn't even being called, and I don't know where's my mistake. What exactly works and what doesn't is marked with commentaries in the code bellow.
My server-side code:
"use strict";
const http = require("http");
const express = require("express");
const { Server } = require("socket.io");
const { log } = console;
const app = express();
const server = http.createServer(app);
const io = new Server(server);
app.use(express.urlencoded({extended: false}));
app.use(express.json());
app.use(express.static(__dirname + "/public"));
io.on("connect", socket => {
const { id } = socket;
io.emit("receiveMsg", id); // This works
})
io.on("sendMsg", msg => { // This doesn't work
log("sendMsg: " + msg);
});
server.listen(8080);
My client-side code:
const socket = io();
const { log } = console;
socket.on("receiveMsg", msg => { // This works
log("receiveMsg: " + msg);
});
const sendMsg = () => {
const msg = document.querySelector("#msg").value;
socket.emit("sendMsg", msg); // This doesn't work
}
My client-side HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test</title>
</head>
<body>
<h1>Hello, world!</h1>
<input type="text" id="msg" placeholder="msg">
<button onclick="sendMsg()">send</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.1.3/socket.io.js"></script>
<script>
// Client-side code here
</script>
</body>
</html>
based on the doc https://socket.io/docs/v4/client-socket-instance/
the connection event is connection on server side, and connect on client side
// server-side
io.on("connection", (socket) => {
console.log(socket.id); // x8WIv7-mJelg7on_ALbx
});
// client-side
socket.on("connect", () => {
console.log(socket.id); // x8WIv7-mJelg7on_ALbx
});
for Emit events, if you see here https://socket.io/docs/v4/emitting-events/
it seems requires us to put the subscription event inside connection block
// server-side
io.on("connection", (socket) => {
socket.on("hello", (arg) => {
console.log(arg); // world
});
});
// client-side
socket.emit("hello", "world");
so maybe you can try to change your server code
io.on("connection", (socket) => {
socket.on("sendMsg", msg => { // This doesn't work
log("sendMsg: " + msg);
}
});
it uses socket.on, not io.on on server side
I am new to nodejs,how come sockets get connected automatically till I stop the server.It should connect one socket at a time?
After I open html page in browser sockets keep on getting connected on their own!
It is expected that only one socket should be connected after server starts running.
How can I connect one socket at a time?
server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
users = [];
connections =[];
server.listen(process.env.port || 3000);
console.log('Server running');
app.get('/',function(req,res){
res.sendFile(__dirname + '/index.html');
});
io.sockets.on('connection',function(socket){
connections.push(socket);
console.log('Connected: %s sockets connected',connections.length);
socket.on('disconnect',function(data){
connections.splice(connections.indexOf(socket), 1);
console.log('Disconnected %s sockets connected',connections.length);
});
socket.on('send message',function(data){
io.sockets.emit('new message',{msg : data});
});
});
index.html
<!doctype html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap /3.3.6/css/bootstrap.min.css">
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="/socket.io/socket.io.js /"></script>
<style>
body{
margin-top:30px;}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="well">
<h3> Online users </h3>
<ul class="list-group" id="users"> </ul>
</div>
</div>
<div class="col-md-8">
<div class="chat" id="chat">
<form id="messageForm">
<div class="form-group">
<label>Enter Message</label>
<textarea class="form-control" id="message"></textarea>
</br>
<input type="submit" class="btn btn-primary" value="Send message"/>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
$(function(){
var socket = io.connect();
var $messageForm = $('#messageForm');
var $message = $('#message');
var $chat = $('#chat');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send message', $message.val());
$message.val('');
});
socket.on('new message',function(data){
$chat.append('<div class="well">'+data.msg+'</div>');
});
});
</script>
</body>
</html>
Here is a bit more complete solution with some notes for you.
Socket.io has long had some snafus with multiple connections. This can and will happen for things such as intermittent connectivity between client and server to past bugs.
You may want to also checkout ws on npmjs.com see > https://www.npmjs.com/package/ws
For some reference as to how templating works in NodeJS/Express see > https://expressjs.com/en/advanced/developing-template-engines.html
Hopefully this will put you in the right direction...
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);
const cons = require('consolidate'); // enables using any template engine.
server.maxConnections = 5; // you can limit connections to server if you wish.
const connections = [];
// Handle your template & engine.
app.engine('html', cons.swig); // where "swig" is the template lang u want to use.
app.set('views', 'your/path/to/views'); // where your views folder lives.
app.set('view engine', 'html'); // the extension of the templates without "."
app.get('/', function (req, res) {
res.render('index', { /* your locals here */ });
});
io.sockets.on('connection', function (socket) {
connections.push(socket);
console.log('Connected: %s sockets connected', connections.length);
socket.on('disconnect', function (data) {
connections.splice(connections.indexOf(socket), 1);
console.log('Disconnected %s sockets connected', connections.length);
});
socket.on('send message', function (data) { // wouldn't use event names with spaces
io.sockets.emit('new message', { // you could do something like 'message:new' & 'message:received' for the above.
msg: data
});
});
});
server.listen(process.env.port || 3000, () => {
const address = server.address();
const host = address.address;
const port = address.port;
console.log(`Server listening at ${host}:${port}.`);
});
// NOTE: Below handles ctrl-c for Win //
// This will allow for graceful shutdown of connections.
if (process.platform === "win32") { // this is required for handling on windows.
var rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("SIGINT", function () {
process.emit("SIGINT");
});
}
process.on("SIGINT", function () {
connections.forEach((socket) => {
// destroy your sockets here!
});
process.exit();
});
I'm fairly new to Nodejs and I'm building an app that ssh to a remote machine and get a tail -f of a log file.
The lines of the log file I'm receiving I'm sending to the client via socket-io (ver. 2.0.3)
Now I'm facing a problem that when a second browser tries to tail a different log, the new log is sent to both of the browsers instead of only the one who made the request.
I'm not sure if it's a problem with my socket-io code or the child_process.
Here's the server:
const express = require('express'),
app = express(),
path = require('path'),
bodyParser = require('body-parser'),
logger = require('morgan'),
server = require('http').Server(app),
io = require('socket.io')(server),
spawn = require('child_process').spawn,
events = require('events'),
eventEmitter = new events.EventEmitter();
// Fix body of requests
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// Log the requests
app.use(logger('dev'));
// Serve static files
app.use(express.static(path.join(__dirname, '.')));
// Add a basic route – index page
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
io.on('connection', (socket) => {
console.log(`client connected ${socket.client.id}`);
eventEmitter.on('tail', (data) => {
socket.tail = spawn('ssh', ['root#' + 'quality-p.company.com', 'tail -f', data.service], { shell: true });
socket.tail.stdout.on('data', (data) => {
console.log(`got new data ${data.toString()}`);
socket.emit('newLine', {line: data.toString().replace(/\n/g, '<br />')});
});
});
});
app.get('/tail', (req, res) => {
eventEmitter.emit('tail', req.query);
res.sendStatus(200);
});
// Bind to a port
server.listen(3005, () => {
console.log('running on localhost:' + 3005);
});
Client:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="./node_modules/socket.io-client/dist/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$(() => {
let socket = io();
socket.on('connect', () => {
console.log('connected');
});
socket.on('newLine', (data) => {
console.log(`new data: ${data.line}`);
$("#tailing").append(data.line);
});
$('#tail').click(() => {
$.get('/tail', {
service: $('#service').val()
});
});
});
</script>
<title>Title</title>
</head>
<body>
<select id="service">
<option id="tnet" value="/var/log/tnet">tnet</option>
<option id="consul" value="/var/log/consul">consul</option>
</select>
<button id="tail">tail</button>
<div id="tailing" style="background-color: antiquewhite;">
</div>
</body>
</html>
Server
const express = require('express'),
app = express(),
path = require('path'),
bodyParser = require('body-parser'),
logger = require('morgan'),
server = require('http').Server(app),
io = require('socket.io')(server),
spawn = require('child_process').spawn;
// Fix body of requests
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
// Log the requests
app.use(logger('dev'));
// Serve static files
app.use(express.static(path.join(__dirname, '.')));
// Add a basic route – index page
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
var tails = {};
io.on('connection', (socket) => {
console.log(`client connected ${socket.client.id}`);
socket.on('tail', (data) => {
socket.join(data.service);
if (typeof tails[data.service] == "undefined") {
tails[data.service] = spawn('ssh', ['root#' + 'quality-p.company.com', 'tail -f', data.service], {
shell: true
});
tails[data.service].stdout.on('data', (data) => {
console.log(`got new data ${data.toString()}`);
io.to(data.service).emit('newLine', {
line: data.toString().replace(/\n/g, '<br />')
});
});
}
});
});
// Bind to a port
server.listen(3005, () => {
console.log('running on localhost:' + 3005);
});
Client
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="./node_modules/socket.io-client/dist/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$(() => {
let socket = io();
socket.on('connect', () => {
console.log('connected');
});
socket.on('newLine', (data) => {
console.log(`new data: ${data.line}`);
$("#tailing").append(data.line);
});
$('#tail').click(() => {
socket.emit('tail', {
service: $('#service').val()
});
});
});
</script>
<title>Title</title>
</head>
<body>
<select id="service">
<option id="tnet" value="/var/log/tnet">tnet</option>
<option id="consul" value="/var/log/consul">consul</option>
</select>
<button id="tail">tail</button>
<div id="tailing" style="background-color: antiquewhite;">
</div>
</body>
</html>
When a user clicks an html button (#new) I want to store their socket.id into an array (userQueue) on my node server but I'm having trouble figuring out how to do this. Do I need to set up a post request or is there a way through socket.io?
App.js (Server):
// App setup
var express = require('express'),
socket = require('socket.io'),
app = express(),
bodyParser = require("body-parser");
var server = app.listen(3000, function() {
console.log('listening to requests on port 3000');
});
var io = socket(server);
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static('public'));
// Room Logic
var userQueue = [];
io.on('connection', function(socket) {
console.log('made socket connection', socket.id);
socket.on('chat', function(data) {
io.sockets.emit('chat', data);
});
socket.on('typing', function(data) {
socket.broadcast.emit('typing', data);
});
});
Chat.js (client side):
// Make connection
var socket = io.connect('http://localhost:3000');
// Query DOM
var message = document.getElementById('message');
handle = document.getElementById('handle'),
btn = document.getElementById('send'),
btnNew = document.getElementById('new'),
output = document.getElementById('output'),
feedback = document.getElementById('feedback');
// Emit events
btn.addEventListener('click', function(){
socket.emit('chat', {
message: message.value,
handle: handle.value
});
});
message.addEventListener('keypress', function() {
socket.emit('typing', handle.value);
});
// Listen for events
socket.on('chat', function(data) {
feedback.innerHTML = ""
output.innerHTML += '<p><strong>' + data.handle + ':</strong>' + data.message + '</p>'
});
// Emit 'is typing'
socket.on('typing', function(data) {
feedback.innerHTML = '<p><em>' + data + ' is typing a message...</em></p>'
});
Index.html:
<!DOCTYPE html>
<html>
<head>
<title>WebSockets 101</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<link rel="stylesheet" type="text/css" href="/styles.css">
</head>
<body>
<div id="mario chat">
<div id="chat-window">
<div id="output"></div>
<div id="feedback"></div>
</div>
<input id="handle" type="text" placeholder="Handle">
<input id="message" type="text" placeholder="Message">
<button id="send">Send</button>
<button id="new">New</button>
</div>
<script type="text/javascript" src="/chat.js"></script>
</body>
</html>
I believe that a post request will probably work as well, but if you want to simply work with socket.io you can consider doing something similar to your chat event by adding this in your chat.js:
btnNew.addEventListener('click', function() {
socket.emit('new user', socket.id);
});
And on the server side, app.js:
socket.on('new user', function(id) {
userQueue.push(id);
});
And it should be stored in the array. Hope this helps!
Created a sample scalable application using nodejs connected with mysql database in openshift . But I got 502 error bad gateway.changed #option httpchk GET / in haproxy.
I have a database testnodejs having table users(id int,name varchar);
my sample code
index.html
<!doctype html>
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#submit').click(function () {
$.get('/users',data,function(data){
});
});
});
</script>
</head>
<body>
<h3>Enter a username</h3>
<input id="user" type="text" />
<input id="submit" type="submit" />
<p id="output"></p>
</body>
</html>
app.js
var express = require('express'),
mysql = require('mysql');
var ipaddr = process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1";
var port = process.env.OPENSHIFT_NODEJS_PORT || 3000;
var app = module.exports = express.createServer();
var connection = mysql.createConnection({
host : process.env.OPENSHIFT_MYSQL_DB_HOST,
user : process.env.OPENSHIFT_MYSQL_DB_USERNAME,
password :process.env.OPENSHIFT_MYSQL_DB_PASSWORD,
port :process.env.OPENSHIFT_MYSQL_DB_PORT,
db :"testnodejs"
});
app.use(express.bodyParser());
connection.connect();
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html');
});
app.get('/users', function(req, res){
connection.query("select * from users where name="+req.query["name"],
function(err, result, fields) {
if (err) throw err;
else {
res.send(result);
}
});
});
app.listen(port,ipaddr);
console.log("Express server listening on port %d in %s mode",port, ipaddr, app.settings.env);