Node.js Socket.io Error when trying to connect client to server - node.js

I am trying to create a Web chat and to do this 1st we need to set up a client to server connection via Node and Socket.io - and it is not working.
The server code is here:
https://collectiveboost.com/cb_node/chat_app/server.js
And it runs fine when started via: node server.js
printing results to putty command line of: “Socket io Server Chat Started...”
But on client side the socket.io connection is not happening :(
And we have tried it both ways, that is via global socket.io as you can see here:
https://collectiveboost.com/cb_node/chat_app/index.htm
this results in Error:
Failed to load resource: the server responded with a status of 404 (Not Found)
Uncaught Reference Error: io is not defined at (index):14
And via local version of the client-side JS file which can be reached via: node_modules/socket.io/client-dist/socket.io.js
as stated on:
https://socket.io/get-started/chat
which you can see here:
https://collectiveboost.com/cb_node/chat_app/index_2.htm
this results in Error:
polling-xhr.js:157 GET https://collectiveboost.com/socket.io/?EIO=4&transport=polling&t=Nt9UN_R 404 (Not Found)
So what are we doing wrong?
How can we connect the client side Web page socket.io to server?
Thanks

please try this code and its very usefull to you.
Its a basic simple chat system.
Server Code
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index6.html');
});
var username = '';
var rooms;
io.on('connection', function(socket) {
console.log("User connected");
socket.on('join', function(name) {
username = name;
//console.log(username)
io.emit('chat-msg', `${username.toUpperCase()} Welcome`);
})
socket.join(rooms)
socket.on('chat msg', function(msg) {
//console.log(msg);
io.sockets.in(rooms).emit('chat msg', msg)
//console.log(array)
})
socket.on('disconnect', function(name) {
console.log("disconnet")
io.emit('chat-msg', `${username.toUpperCase()} disconnected`)
})
});
http.listen(5600, function() {
console.log('listening on localhost:5600');
});
Client Code
<!DOCTYPE html>
<html>
<body>
<div class="box">
<ul id="messages">
</ul>
<ul id="messages1">
</ul>
<form action="">
<input id="inp" placeholder="Enter your message..." autocomplete="off" required /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
var name = prompt("enter name")
var socket = io();
socket.emit('join', name);
$('form').submit(function(event) {
event.preventDefault();
socket.emit("chat msg", (name + " : " + $("#inp").val()));
//$('#messages').append($('<li id="list">').text('You: ' +$('#inp').val()));
$('#inp').val('');
});
socket.on('chat-msg', function(msg) {
$('#messages').append($('<li id="list"><br>').text(msg));
})
socket.on('chat msg', function(msg) {
$('#messages1').append($('<li id="list1"><br>').text(msg));
})
socket.on('left', function(data) {
document.write(data.description)
})
</script>
</div>
<style>
.box {
border: 1px solid red;
height: auto;
width: 500px;
position: absolute;
right: 300px;
border-radius: 10px;
padding: 30px;
}
#inp {
position: absolute;
bottom: 10px;
right: 200px;
outline: none;
border: soild blue;
border-radius: 5px;
}
ul {
list-style-type: none;
padding: 50px;
text-align: center;
}
#list {
text-align: center;
background-color: #6195e8;
color: #fffafa;
border-radius: 10px;
}
#list1 {
text-align: right;
background-color: #6bdde3;
color: #ed001c;
}
button {
color: White;
background-color: green;
width: 80px;
border-radius: 10px;
position: absolute;
right: 150px;
bottom: 10px;
}
#messages li {
padding: 5px 10px;
}
</style>
</body>
</html>

Related

A method of calling an api of node.js from react.js

After crawling a part of the university to node.js, we try to call an api of node.js to react.js.
In the node.js file, Title and url of the link were retrieved, and in the react.js file, List and ListItem were configured to receive api data.
The problem is that I don't know how to call tittle and url from react.js, which are data crawled in node.js.
Also, I ask because I don't know how to insert the called api into the list of react.js.
This is App.js :
import React from 'react';
import HeaderTemplate from './components/HeaderTemplate';
import MainTemplate from './components/MainTemplate';
import FooterTemplate from './components/FooterTemplate';
const App = () => {
return (
<div>
<HeaderTemplate/>
<MainTemplate/>
<FooterTemplate/>
</div>
);
};
export default App;
This is MainTemplate.js :
import React from 'react';
import styled from 'styled-components';
import NoticesList from './NoticesList';
const MainTemplate = () => {
const Main = {
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
padding: '60px',
};
const Section01 = {
margin: '25px',
width: '55%',
height: '80vh',
backgroundColor: '#eeeeee',
fontSize: '45px',
textAlign: 'center',
};
const Section02 = {
margin: '25px',
width: '45%',
height: '80vh',
backgroundColor: '#ff0000',
fontSize: '45px',
textAlign: 'center',
};
return (
<div className="Main" style={Main}>
<div className="Section01" style={Section01}>
비교과
<NoticesList />
</div>
<div className="Section02" style={Section02}>
튜터링 및 학공
</div>
</div>
);
};
export default MainTemplate;
This is NoticesItem.js :
import React from 'react';
import styled from 'styled-components';
const NoticesItemBlock = styled.div`
display: flex;
.contents {
h6 {
margin: 15px;
a {
color: black;
}
}
}
& + & {
margin-top: 1.5rem;
}
`;
const NoticesItem = ({ article }) => {
const { title, url } = article;
return (
<NoticesItemBlock>
<div className="contents">
<h6>
<a href={url} target="_blank" rel="noopener noreferrer">
{title}
</a>
</h6>
</div>
</NoticesItemBlock>
);
};
export default NoticesItem;
This is NoticesList.js :
import React from 'react';
import styled from 'styled-components';
import NoticesItem from './NoticesItem';
const NoticesListBlock = styled.div`
box-sizing: border-box;
padding-bottom: 3rem;
width: 768px;
margin: 0 auto;
margin-top: 2rem;
`;
const sampleArticle = {
title: 'title',
url: 'https://google.com',
};
const NoticesList = () => {
return (
<NoticesListBlock>
<NoticesItem article={sampleArticle} />
<NoticesItem article={sampleArticle} />
<NoticesItem article={sampleArticle} />
<NoticesItem article={sampleArticle} />
</NoticesListBlock>
);
};
export default NoticesList;

Cannot signal after peer is destroyed . Simple-peer

I'm a beginner in webrtc . I have used simple-peer to connect two peers on a video calling application .
When a second peer is connected , his video is displayed but after a few seconds an error showing "cannot signal when peer is destroyed" is thrown . I dont know where I'm going wrong . I have attached the code below .
The code error is thrown in this line :
PeerRef.current.signal(signal);
client.js :
import React, { useEffect,useRef } from 'react';
import io from 'socket.io-client';
import Peer from 'simple-peer';
import styled from 'styled-components';
const Container = styled.div`
display: flex;
width: 100%;
height: 100vh;
flex-direction: row;
`;
const LeftRow = styled.div`
width: 40%;
height: 100%;
`;
const RightRow = styled.div`
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
`;
const Video = styled.video`
height: 50%;
width: 100%;
border: 1px solid black;
`;
const Room=(props)=>{
const socketRef=useRef();
const userRef=useRef();
const partnerRef=useRef();
const PeerRef=useRef();
useEffect(()=>{
navigator.mediaDevices.getUserMedia({video:true,audio:true}).then((stream)=>{
userRef.current.srcObject=stream;
socketRef.current=io.connect('/');
console.log("hello");
console.log(props.match.params.roomID);
socketRef.current.emit("join room",props.match.params.roomID);
socketRef.current.on("other user",(PartnerID)=>{
console.log("creator");
if(PartnerID){
console.log("partner");
PeerRef.current=createPeer(PartnerID,socketRef.current.id,stream);
}
});
socketRef.current.on("caller signal",(incoming)=>{
console.log("Caller signal from browser");
PeerRef.current=addPeer(incoming.CallerID,incoming.signal,stream);
});
socketRef.current.on("callee signal",(signal)=>{
console.log("callee signal from browser");
PeerRef.current.signal(signal);
});
})
},[]);
function handleStream(stream){
partnerRef.current.srcObject=stream;
}
const createPeer = (PartnerID,CallerID,stream) =>{
const peer = new Peer({
initiator:true,
trickle:false,
stream
});
peer.on("signal",(signal)=>{
const payload={
PartnerID,
CallerID,
signal
}
socketRef.current.emit("call partner",payload);
});
peer.on("stream",handleStream);
//peer.on("data",handleData);
return peer;
}
const addPeer = (CallerID,insignal,stream) =>{
console.log("inside addpeer");
const peer = new Peer({
initiator:false,
trickle:false,
stream
});
peer.on("signal",(signal)=>{
console.log("inside peer");
const payload={
CallerID,
signal
}
socketRef.current.emit("accept call",payload);
});
peer.on("stream",handleStream);
peer.signal(insignal);
return peer;
}
return(
<Container>
<LeftRow>
<Video autoPlay ref={userRef} />
<Video autoPlay ref={partnerRef} />
</LeftRow>
<RightRow>
</RightRow>
</Container>
);
}
export default Room;
server.js:
const express = require("express");
const http = require("http");
const app = express();
const server = http.createServer(app);
const socket = require("socket.io");
const io = socket(server);
server.listen(5000);
const rooms={};
io.on('connection',(socket)=>
{
console.log("Connected");
socket.on("join room",(roomID)=>{
console.log("User here");
if(rooms[roomID])
rooms[roomID].push(socket.id);
else
rooms[roomID]=[socket.id];
const otherUser = rooms[roomID].find(id => id!==socket.id);
socket.emit("other user",otherUser);
});
socket.on("call partner",(incoming)=>{
console.log("call partner from server");
const payload={
CallerID:incoming.CallerID,
signal:incoming.signal
}
io.to(incoming.PartnerID).emit("caller signal", payload);
});
socket.on("accept call",(incoming)=>{
console.log("accept call");
io.to(incoming.CallerID).emit("callee signal",incoming.signal);
});
});
Had the same error, I was using version 9.7.2 of simple-peer. It seems to have a bug, so bringing the version down to 9.6.2 fixed the error.

How to render a page in pug template engine in node.js

I want to render a page when I click on Signin. I use a Service Oriented Architecture, in which I use the Pug Template Engine for making an Admin-Panel. When I click on SignIn, it give the error below.
{"error":{"message":"Not found"}}
I don't know where I made a mistake. Please help me.
Here is the welcome.pug code where there is a Signin link. Please see if I use the correct url or not.
doctype html
html(lang='{{ app()->getLocale() }}')
head
meta(charset='utf-8')
meta(http-equiv='X-UA-Compatible', content='IE=edge')
meta(name='viewport', content='width=device-width, initial-scale=1')
title QuizLit
// Fonts
link(href='https://fonts.googleapis.com/css?family=Raleway:100,600', rel='stylesheet', type='text/css')
// Styles
style.
html, body {
background-color: #fff;
color: #636b6f;
font-family: 'Raleway', sans-serif;
font-weight: 100;
height: 100vh;
margin: 0;
}
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.top-right {
position: absolute;
right: 10px;
top: 18px;
}
.content {
text-align: center;
}
.title {
font-size: 84px;
}
.links > a {
color: #636b6f;
padding: 5px 25px;
font-size: 24px;
font-weight: 600;
letter-spacing: .1rem;
text-decoration: none;
text-transform: uppercase;
border: solid 1px #636b6f;
border-radius: 50px;
}
.m-b-md {
margin-bottom: 30px;
}
body
.flex-center.position-ref.full-height
.content
.title.m-b-md
| Welcome to QuizLit
.links
a(href='/login') Sign in
Here is the structure of my code.
Here is the login.pug file
include ../layout/main
block content
// Horizontal Form
.login-box
.login-logo
a(href='/')
b Admin
// /.login-logo
.login-box-body
p.login-box-msg Sign in to start your session
form(role='form', method='POST', action="/login")
ul.text-danger
.has-feedback(class="form-group{{ $errors->has('email') ? ' has-error' : '' }}")
input#email.form-control(type='email', name='email', value=" ", placeholder='Email', required='')
//- | #if ($errors->has('email'))
span.help-block
//- strong {{ $errors->first('email') }}
//- | #endif
span.glyphicon.glyphicon-envelope.form-control-feedback
.has-feedback(class="form-group{{ $errors->has('password') ? ' has-error' : '' }}")
input#password.form-control(type='password', name='password', placeholder='Password', required='')
//- | #if ($errors->has('password'))
span.help-block
//- strong {{ $errors->first('password') }}
//- | #endif
span.glyphicon.glyphicon-lock.form-control-feedback
.row
.col-xs-7.col-xs-offset-1
.checkbox.icheck
label
input(type='checkbox')
| Remember Me
// /.col
.col-xs-4
button.btn.btn-primary.btn-block.btn-flat(type='submit') Sign In
// /.col
//- | #section('page_specific_scripts')
script(src="/plugins/iCheck/icheck.min.js")
script.
$(function () {
$('input').iCheck({
checkboxClass: 'icheckbox_square-blue',
radioClass: 'iradio_square-blue',
increaseArea: '20%' /* optional */
});
});
And here is the Api.js code:
'use strict'
const express = require('express');
const router = express.Router();
const adminAuthService = require('../service/adminAuthService');
const middlewares = require('../../../base/service/middlewares/accessControl');
router.post("/login", (req, res, next) => {
adminAuthService.login(req.body)
.then(data => {
return res.send(data)
}, err => next(err))
});
router.post("/createstudent", middlewares.assertUserIsAdmin, (req, res, next) => {
// router.post("/createstudent", (req, res, next) => {
adminAuthService.signupStudent(req.body)
.then(data => {
return res.send(data)
}, err => next(err))
});
module.exports = router;
Here is the Index.js file:
'use strict'
const express = require('express');
const router = express.Router();
const adminRoutes = require("./admin");
const teacherRoutes = require("./teacher");
const appRoutes = require("./api");
router.use("/admin", adminRoutes);
router.use("/teacher", teacherRoutes);
router.use("/api", appRoutes);
router.get('/', (req, res, next) => {
res.render('welcome');
})
module.exports = router
How should I separately define the Web Routes and Api Routes to use a Service Oriented Architecture in Node.js.
Firstly you do not have any /login route in the index.js file, so /login on the button would not work.
Secondly you don't seem to have any route handler which will render the login.pug file.
You can define this in the index.js file as a GET route
router.get('/login', (req, res, next) => {
res.render('login');
});
You can even keep this route handler in your api.js file in which case the effective route for the button would be
.links
a(href='/api/login') Sign in
Another thing that may help is including a POST method request in your pug file.
At the moment, it appears you only have an API endpoint for /login listening for POST requests.
#stephen suggested you add a get route. If you don't want to or can't do that, you need to call /login with a POST method. Make sure to pass along the user information needed to authenticate them.

How to use OpenLayers 5 with Node (express)?

I've been trying to visualize Vector data. I'm using Tegola as vector tile server. My first choice of visualizing library was Leaflet, but Leaflet's Vector.Grid library seems to have some problems with point data;
Issue on tegola's Github page.
Issue on Leaflet.VectorGrid project on Github.
So I've switched to OpenLayers. OpenLayers has a very inclusive library and there are plenty of examples and tutorials.
It took half a day for me to understand new version and complete the workshop on the link above. OpenLayers seems to be the solution for my needs. But I don't know how to rewrite code the code that I've prepared in workshop which is written to run on web.pack server. I want to render the layers and add a few nodes that will complete my needs on the map.
My map runs on web.pack server ;
But I want to render this map in Node. So I've write a server file;
// Get dependencies
const express = require('express');
const http = require('http');
const bodyParser = require('body-parser');
const dotenv = require('dotenv')
const logger = require('./services/logger');
const cors = require('cors');
const { Pool, Client } = require('pg')
const pool = new Pool()
dotenv.config();
// Get our API routes
const api = require('./routes/api.router');
const client = new Client()
const app = express();
// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/script'));
app.get('/', function (req, res) {
// res.sendFile(__dirname + "/views/index.html");
res.render('index', { title: 'Map' });
});
// Set our api routes
app.use('/api', api);
app.use((req, res, next) => {
const err = new Error('Not Found');
err.status = 404;
logger.error(`Request Error ${req.url} - ${err.status}`)
next(err);
});
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
error: {
message: err.message
}
});
});
/**
* Get port from environment and store in Express.
*/
const port = process.env.PORT || '3000';
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`API running on localhost:${port}`));
Confusing part starts from here, I'm using the same HTML file in workshop server(web.pack). But I don't know how to reference main.js file to this HTML file. As you can see below there is no reference to main.js file inside this file.
How does web.pack combines these two files ? And is it possible to the same using express in NodeJS ?
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OpenLayers</title>
<style>
html,
body,
#map-container {
margin: 0;
height: 100%;
width: 100%;
font-family: sans-serif;
}
.arrow_box {
position: relative;
background: #000;
border: 1px solid #003c88;
}
.arrow_box:after,
.arrow_box:before {
top: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.arrow_box:after {
border-color: rgba(0, 0, 0, 0);
border-top-color: #000;
border-width: 10px;
margin-left: -10px;
}
.arrow_box:before {
border-color: rgba(0, 60, 136, 0);
border-top-color: #003c88;
border-width: 11px;
margin-left: -11px;
}
.arrow_box {
border-radius: 5px;
padding: 10px;
opacity: 0.8;
background-color: black;
color: white;
}
#popup-content {
max-height: 200px;
overflow: auto;
}
#popup-content th {
text-align: left;
width: 125px;
}
</style>
</head>
<body>
<div id="map-container"></div>
<div class="arrow_box" id="popup-container">
<div id="popup-content"></div>
</div>
</body>
</html>
main.js
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import MVT from 'ol/format/MVT';
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorTileSource from 'ol/source/VectorTile';
import TileLayer from 'ol/layer/Tile';
import XYZSource from 'ol/source/XYZ';
import Overlay from 'ol/Overlay';
import { Style, Fill, Stroke, Circle, Text } from 'ol/style';
import { fromLonLat } from 'ol/proj';
const map = new Map({
target: 'map-container',
view: new View({
center: fromLonLat([34.633623, 39.818770]),
zoom: 7
})
});
const layer = new VectorTileLayer({
source: new VectorTileSource({
attributions: [
'© OpenMapTiles',
'© OpenStreetMap contributors'
],
format: new MVT(),
url: `http://localhost:8090/maps/observation/{z}/{x}/{y}.vector.pbf`,
maxZoom: 24,
type: 'base'
})
});
const baseLayer = new TileLayer({
source: new XYZSource({
url: 'http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg'
}),
type: 'base'
});
map.addLayer(baseLayer);
const overlay = new Overlay({
element: document.getElementById('popup-container'),
positioning: 'bottom-center',
offset: [0, -10],
autoPan: true
});
map.addOverlay(overlay);
overlay.getElement().addEventListener('click', function () {
overlay.setPosition();
});
map.addLayer(layer);
layer.setStyle(function (feature, resolution) {
const properties = feature.getProperties();
if (properties.layer == 'temperature_stations' || properties.layer == 'temperature_stations_simple') {
const point = new Style({
image: new Circle({
radius: 5,
fill: new Fill({
color: 'red'
}),
stroke: new Stroke({
color: 'grey'
})
})
})
return point
}
if (properties.layer == 'aws_stations') {
const point = new Style({
image: new Circle({
radius: 5,
fill: new Fill({
color: 'blue'
}),
stroke: new Stroke({
color: 'grey'
})
})
})
return point
}
if (properties.layer == 'spa_stations') {
const point = new Style({
image: new Circle({
radius: 10,
fill: new Fill({
color: 'green'
}),
stroke: new Stroke({
color: 'grey'
})
})
})
return point
}
if (properties.layer == 'syn_stations') {
const point = new Style({
image: new Circle({
radius: 10,
fill: new Fill({
color: 'purple'
}),
stroke: new Stroke({
color: 'grey'
})
})
})
return point
}
});
map.on('pointermove', function (e) {
let markup = '';
map.forEachFeatureAtPixel(e.pixel, function (feature) {
markup += `${markup && '<hr>'}<table>`;
const properties = feature.getProperties();
for (const property in properties) {
markup += `<tr><th>${property}</th><td>${properties[property]}</td></tr>`;
}
markup += '</table>';
}, { hitTolerance: 0 });
if (markup) {
document.getElementById('popup-content').innerHTML = markup;
overlay.setPosition(e.coordinate);
} else {
overlay.setPosition();
}
});
The workshop uses the webpack dev server to serve the application for development. The last chapter explains how to build the application for production: https://openlayers.org/workshop/en/deploying/. The steps explained there explain how to use webpack to give you a static web application, You'll be using the resulting artifacts in your Express application as static files: https://expressjs.com/en/starter/static-files.html.

template design for sending mail using nodejs

This is my code. When it runs in Postman it shows error like cannot get method.
var sendTempMail = function (req,res)
{
const nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
auth: {
user: 'transactions#gmail.com',
pass: 'qwertyu#'
}
});
let mailOptions = {
from: 'transactions#gmail.com',
to: 'xxxxxx#gmail.com','yyyyyyyy#gmail.com',zzzzzz#mydomain.com,//here to:receiver not accept more than one
subject: 'mail notification Test',
text: 'Hello !!!!!!!!!everything works fine'
html:<h1>Notification mail</h1>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 10px;
text-align: left;
}
</style>
</head>
<body>
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</body>
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log("mail not sent" +error.message);
}
console.log('success');
});
};
module.exports = {
newTemplate :newTemplate,
sendTempMail : sendTempMail
};
Please paste your error message with your question. However I can see one mistake that the HTML parameter has all raw html pasted there. It should be in string format.
Please check line no 44 in the code in below link
https://github.com/nodemailer/nodemailer/blob/master/examples/full.js

Resources