Server - node.js I send the file to the server with ajax request, the progress of the download is displayed. There is a button that stops this ajax request (xhr.abort ()). After pressing the "stop" button, the server crashes with request aborted. What to do?
app.post("/blog/add", function (req, res, next) {
//Проанализируем загрузку файла
var form = new multiparty.Form();
var wayImage = "/files/";
form.on('part', function (part) {
var path = './public/files/' + part.filename;
wayImage += part.filename;
var out = fs.createWriteStream(path);
part.pipe(out);
});
form.on('close', function () {
//Отправка ссылки на картинку
res.send(wayImage);
});
form.on('error', function () {
console.log('error');
});
form.parse(req);
});
Related
How to make sure a callback function has called(fired)?
I am using socket.io and callback function please check out my code:
// server
socket.emit('message', message, function() {
// some code
});
// client
socket.on('message', function(data, callback) {
callback(); // confirm we received the message
// some code
});
I want to know in the server code, to detect whether function has called in the client side or no.
If I understood you well, to detect in your server whether your callback has been called in the client or not, you can use a timer in the server and emit a confirmation in the client.
Let's me explain it further.
1) Server
// Timer to wait for your confirmation
let timer
// Listen message from the Client
socket.on('message', msg => {
// Wait 5 s for confirmation
timer = setTimeout(() => noConfirmation(), 5000)
// Send message to the Clients
io.emit('message', msg)
})
2) Client
// Listen message from the Server
socket.on('message', msg => {
// Send confirmation (your callback)
socket.emit('confirmation', id)
})
3) Server
// Listen confirmation from the Client
socket.on('confirmation', id => {
// Avoid timer
clearTimeout(timer)
// Send back confirmation
io.emit('confirmation', id)
})
Here you are a full working example:
Server (index.js)
const app = require('express')()
const http = require('http').createServer(app)
const io = require('socket.io')(http)
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html')
})
// Timer to wait for your confirmation
let timer
io.on('connection', socket => {
console.log('a user connected')
socket.on('disconnect', () =>
console.log('user disconnected'))
// Listen message from the Client
socket.on('message', msg => {
console.log(`message: ${msg}`)
// Wait 5 s for confirmation
timer = setTimeout(() => console.log('☓'), 5000)
// Send message to the Clients
io.emit('message', msg)
})
socket.on('confirmation', id => {
console.log('✓')
// Avoid timer
clearTimeout(timer)
// Send back confirmation
io.emit('confirmation', id)
})
})
http.listen(3000, () =>
console.log('listening on *:3000'))
Client (index.html)
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io()
// Submit message to the Server
const $input = document.querySelector('input');
document.querySelector('form').onsubmit = e => {
e.preventDefault() // prevents page reloading
socket.emit('message', $input.value)
$input.value = ''
}
// Listen message from the Server
const $messages = document.querySelector('#messages');
socket.on('message', msg => {
const id = new Date().getTime()
$messages.insertAdjacentHTML('beforeend', `<li id="m${id}">${msg}</li>`)
// Send confirmation
socket.emit('confirmation', id)
})
// Confirmation message recived
socket.on('confirmation', id =>
document.querySelector(`#m${id}`).insertAdjacentText('beforeend', '✓'))
</script>
</body>
If you don't receive the check symbol (✓) it means there was a problem with the messages and in the server after 5 seconds we show a cross symbol (☓), also you can use any function you want in both cases. We are covering both directions.
Hope this help or at least point you to the right direction : )
You can transform your function to make it async (See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
It will look like this:
socket.on('message', async function(data, callback) {
const result = await callback(); // confirm we received the message
console.log(result); //returns whatever the callback function returned
});
I made a server on NodeJs using module Express. Now I want to implement a request from html page with $.ajax by clicking a button. I want to get data from server in json format or in text format, it doesnt matter, but it doesn't work. Why?
And plus why does ajax request reload the html page while it shouldn't?
Server part:
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
var url = require("url");
app.get('/scrape', function (req, res) {
console.log("Someone made request");
url = 'http://spun.fkpkzs.ru/Level/Gorny';
request(url, function (error, response, html) {
if (!error) {
console.log("Inside request");
var $ = cheerio.load(html);
var date, waterlevel;
var json = {
time: "",
waterlevel: ""
};
json.time = $("#waterleveltable td.timestampvalue").first().text()
json.waterlevel = $("#waterleveltable td.value").first().text()
res.send(json);
console.log(json);
}
})
})
app.listen('8081')
console.log('Server started on port 8081');
exports = module.exports = app;
This is my hmlt request:
<form>
<!-- button for sending a request to server-->
<button id="button12">Scrape water height</button>
</form>
<div id="response21">
Print
<!-- div for displaying the response from server -->
</div>
<p id="p1">___!</p>
<script>
$(document).ready(function () {
$("#button12").click(function () {
console.log("Get sent.")
// Json request
$.get("http://localhost:8081/scrape", function (data)
{
console.log("Data recieved" + data);
$("#response21")
.append("Time: " + data.time)
.append("Waterlevel: " + data.waterlevel);
}, "json");
});
});
Because of the fact that your button is inside a form, the default action of clicking the button will be to load a new page. This is what causes the reload of your page.
The simplest thing you can do is a return false at the end of the click handler callback so that to prevent the reload of the page.
Am still new to socket.io, Am trying to pass a value to the server side and store it in a global var which I can then use to do some logic with ARI.
So on my server side I have:
io.sockets.on('muting', function (data) {
mute = data;
console.log("client side:" + mute);
});
Entire server side code for clarity:
var ari = require('ari-client');
var util = require('util');
var chanArr = [];
var test;
var mute;
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
//ARI client
ari.connect('http://localhost:8088', 'asterisk', 'asterisk', clientLoaded);
function clientLoaded(err, client) {
if (err) {
throw err;
}
// find or create a holding bridges
var bridge = null;
client.bridges.list(function (err, bridges) {
if (err) {
throw err;
}
bridge = bridges.filter(function (candidate) {
return candidate.bridge_type === 'mixing';
})[0];
if (bridge) {
console.log(util.format('Using bridge %s', bridge.id));
} else {
client.bridges.create({
type : 'mixing'
}, function (err, newBridge) {
if (err) {
throw err;
}
bridge = newBridge;
console.log(util.format('Created bridge %s', bridge.id));
});
}
});
// handler for StasisStart event
function stasisStart(event, channel) {
console.log(util.format(
'Channel %s just entered our application, adding it to bridge %s',
channel.name,
bridge.id));
channel.answer(function (err) {
if (err) {
throw err;
}
bridge.addChannel({
channel : channel.id
}, function (err) {
var id = chanArr.push(channel.name)
console.log("Value: " + test);
test = channel.name;
updateSip);
if (err) {
throw err;
}
//If else statement to start music for first user entering channel, music will stop once more than 1 enters the channel.
if (chanArr.length <= 1) {
bridge.startMoh(function (err) {
if (err) {
throw err;
}
});
} else if (chanArr.length === 2) {
bridge.stopMoh(function (err) {
if (err) {
throw err;
}
});
} else {}
});
});
}
// handler for StasisEnd event
function stasisEnd(event, channel) {
console.log(util.format(
'Channel %s just left our application', channel.name));
console.log(channel.name);
var index = chanArr.indexOf(channel.name);
chanArr.splice(index, 1);
updateSip();
}
client.on('StasisStart', stasisStart);
client.on('StasisEnd', stasisEnd);
client.start('bridge-hold');
}
//Socket.io logic here
server.listen(3009, function () {
console.log('listening on *:3009');
});
app.use(express.static(__dirname + '/public'));
app.get('/', function (req, res) {
res.sendfile(__dirname + "/testPage.html");
});
io.sockets.on('connection', function (data) {
updateSip();
});
io.sockets.on('muting', function (data) {
mute = data;
console.log("client side:" + mute);
});
function updateSip() {
console.log("Value: " + test);
io.sockets.emit('sip', chanArr);
}
And on my client side:
$(document).on('click', '#kick', function() {
mute = !mute;
socket.emit('muting', mute);
console.log(mute)
});
Full client side code:
jQuery(function ($) {
var socket = io.connect();
var mute = false;
var $sip = $('#sip');
socket.on('sip', function (data) {
var sip = '';
$(".exe").remove();
for (i = 0; i < data.length; i++) {
sip += data[i];
if (sip) {
$sip.append('<tr class="exe">\
<td>' + sip + '</td>\
<td><button class="btn btn-default mute" id="kick" type="submit">Mute</button></td>\
<td><button class="btn btn-default kick" id="kicks" data-toggle="modal" data-target="#myModal" type="submit">Kick</button></td>\
</tr>');
} else {
$sip.append('Currently no extensions');
}
sip = '';
}
});
$('.kick').click(function () {
$('#myInput').focus()
});
$(document).on('click', '#kick', function () {
mute = !mute;
socket.emit('muting', mute);
console.log(mute)
});
});
Am missing something very small, yet cant figure it out.
EDIT: I am not getting error messages, seems am not passing the information server side at all for some reason.
Am using express.
Kind regards.
From socket io doc: http://socket.io/docs/#using-with-the-express-framework
You could try to wrap you 'muting' event listener in the 'connection' event listener. Note that you will use the socket parameter from the 'connection' event to listen to 'muting'
server side:
io.sockets.on('connection',function (socket) {
updateSip();
socket.on('muting', function (data) {
mute = data;
console.log("client side:" + mute);
});
});
var socket = io.connect();
No you are not reaching your server !
//Socket.io logic here
server.listen(3009, function () {
console.log('listening on *:3009');
});
Your socket server seem to be listenning on port 3009, so you have to tell your client where is your server (the path -> ex : http://myoffice.localhost ) and the port to reach the server
try to update client side with :
io.connect("wss://" + document.location.hostname + ':' + 3009);
I am new to this, I built a standard web chat application and I see the power of nodejs, express, socket.io.
What I am trying to do is trigger events from a phone to a website, like a remote control. There is server javascript that listens to events from the client, and client javascript that triggers those events, this is how I understand it correct me if I am wrong.
I learned in the chat app I can send an object from anywhere, as long as they are connected to my server through a specific port http://my-server-ip:3000/. Basically all events are inside the index page, and the connection is index to server to index.
What I am trying to learn is how to trigger events from an external page, I've seen things like http://my-server-ip:3000/ws or something like that, the idea is to connect to a mobile interface that isn't the actual index or website itself, but this interface communicates with the node server using it as a dispatcher to trigger events on the main index page.
Basically what I have learned was index to server to index. I am not sure how I can go custom-page to server to index.
I see that in my app.js, my understanding is that the socket listens to sends which is on the client then it emits the message.
io.sockets.on('connection', function (socket) {
socket.on('sends', function (data) {
io.sockets.emit('message', data);
});
});
I tried creating a test.html that has a button on it, I tried listening to it, here is a screen shot.
Here is my client code
window.onload = function() {
var messages = [];
var socket = io.connect('http://my-server-ip:3000/');
var socketTwo = io.connect('http://my-server-ip:3000/test.html');
var field = document.getElementById("field");
var sendButton = document.getElementById("send");
var content = document.getElementById("content");
var name = document.getElementById("name");
var trigBtn = document.getElementById("trigger-btn");
socket.on('message', function (data) {
if(data.message) {
messages.push(data);
var html = '';
for(var i=0; i<messages.length; i++) {
html += '<b>' + (messages[i].username ? messages[i].username : 'Server') + ': </b>';
html += messages[i].message + '<br />';
}
content.innerHTML = html;
} else {
console.log("There is a problem:", data);
}
});
//FROM DEMO
// sendButton.onclick = sendMessage = function() {
// if(name.value == "") {
// alert("Please type your name!");
// } else {
// var text = field.value;
// socket.emit('send', { message: text, username: name.value });
// field.value = "";
// }
// };
//I include this javascript with test.html and trigger
//this button trying to emit a message to socketTwo
trigBtn.onclick = sendMessage = function() {
socketTwo.emit('send', { message: 'String test here' })
}
}
I am sure that is all wrong, but hopefully this makes sense and someone can help me trigger events from another page triggering to the index.
Here is my app.js server code
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, http = require('http');
var app = express();
var server = app.listen(3000);
var io = require('socket.io').listen(server); // this tells socket.io to use our express server
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
app.get('/test.html', function(req, res) {
res.send('Hello from route handler');
});
io.sockets.on('connection', function (socket) {
socket.emit('message', { message: 'welcome to the chat' });
socket.on('send', function (data) {
io.sockets.emit('message', data);
});
});
All code posted above is just testing cookie cutter code, I am learning from scratch so the above can be totally changed, it's just there as a starter point.
This is so cool I got it to work, so my logic was correct. There were just a few things I was missing. Here it is.
I am not going to post all the server side javascript code, but here is the main logic after listening to the port etc.
// Set a route and in a very dirty fashion I included a script specific
// for this route, earlier I was using one script for both route.
// I also forgot to include the socket.io hence the error in the image above.
app.get('/test', function(req, res) {
res.send('<script src="/socket.io/socket.io.js"></script><script type="text/javascript" src="javascripts/trigger.js"></script><button id="test" class="trigger-btn">Trigger</button>');
});
// This listens to `send` which is defined in the `test` route
// Upon this action the server emits the message which
// is defined inside the index main route I want stuff displayed
io.sockets.on('connection', function (socket) {
socket.on('send', function (data) {
io.sockets.emit('message', data);
});
});
Here is what the index client,js script looks like
window.onload = function() {
var messages = [];
var socket = io.connect('http://my-server-ip:3000');
var content = document.getElementById("content");
socket.on('message', function (data) {
if(data.message) {
messages.push(data);
var html = '';
for(var i=0; i<messages.length; i++) {
html += '<b>' + (messages[i].username ? messages[i].username : 'Server') + ': </b>';
html += messages[i].message + '<br />';
}
content.innerHTML = html;
} else {
console.log("There is a problem:", data);
}
});
}
It was really easy setting up sessions and using them in PHP. But my website needs to deal with WebSockets. I am facing problem to set up sessions in node.js. I can easily push data without using sessions and it would work fine but when more than one tab is opened the new socket.id is created and previously opened tabs won't function properly. So I have been working on sessions and had problem accessing session store, its logging session not grabbed. I have tried with session.load as well but no luck
How do I get session object and use it in a way that opening other tabs wouldn't affect the functionality and push data from server to client on all tabs?
var express=require('express');
var http = require('http');
var io = require('socket.io');
var cookie = require("cookie");
var connect = require("connect"),
MemoryStore = express.session.MemoryStore,
sessionStore = new MemoryStore();
var app = express();
app.configure(function () {
app.use(express.cookieParser());
app.use(express.session({store: sessionStore
, secret: 'secret'
, key: 'express.sid'}));
app.use(function (req, res) {
res.end('<h2>Hello, your session id is ' + req.sessionID + '</h2>');
});
});
server = http.createServer(app);
server.listen(3000);
sio = io.listen(server);
var Session = require('connect').middleware.session.Session;
sio.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
// if there is, parse the cookie
data.cookie = connect.utils.parseSignedCookies(cookie.parse(data.headers.cookie),'secret');
// note that you will need to use the same key to grad the
// session id, as you specified in the Express setup.
data.sessionID = data.cookie['express.sid'];
sessionStore.get(data.sessionID, function (err, session) {
if (err || !session) {
// if we cannot grab a session, turn down the connection
console.log("session not grabbed");
accept('Error', false);
} else {
// save the session data and accept the connection
console.log("session grabbed");
data.session = session;
accept(null, true);
}
});
} else {
// if there isn't, turn down the connection with a message
// and leave the function.
return accept('No cookie transmitted.', false);
}
// accept the incoming connection
accept(null, true);
});
sio.sockets.on('connection', function (socket) {
console.log('A socket with sessionID ' + socket.handshake.sessionID
+ ' connected!');
});
Take a look at this article: Session-based Authorization with Socket.IO
Your code works fine, but need 2 improvements to do what you want (send session data to clients from server):
it extracts sessionID during authorization only
it extracts session data from store by this sessionID during connection where you can send data from server to clients in an interval.
Here's the improved code:
var express = require('express');
var connect = require('connect');
var cookie = require('cookie');
var sessionStore = new express.session.MemoryStore();
var app = express();
app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.session({store: sessionStore, secret: "secret", key: 'express.sid'}));
// web page
app.use(express.static('public'));
app.get('/', function(req, res) {
var body = '';
if (req.session.views) {
++req.session.views;
} else {
req.session.views = 1;
body += '<p>First time visiting? view this page in several browsers :)</p>';
}
res.send(body + '<p>viewed <strong>' + req.session.views + '</strong> times.</p>');
});
var sio = require('socket.io').listen(app.listen(3000));
sio.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
// if there is, parse the cookie
var rawCookies = cookie.parse(data.headers.cookie);
data.sessionID = connect.utils.parseSignedCookie(rawCookies['express.sid'],'secret');
// it checks if the session id is unsigned successfully
if (data.sessionID == rawCookies['express.sid']) {
accept('cookie is invalid', false);
}
} else {
// if there isn't, turn down the connection with a message
// and leave the function.
return accept('No cookie transmitted.', false);
}
// accept the incoming connection
accept(null, true);
});
sio.sockets.on('connection', function (socket) {
//console.log(socket);
console.log('A socket with sessionID ' + socket.handshake.sessionID + ' connected!');
// it sets data every 5 seconds
var handle = setInterval(function() {
sessionStore.get(socket.handshake.sessionID, function (err, data) {
if (err || !data) {
console.log('no session data yet');
} else {
socket.emit('views', data);
}
});
}, 5000);
socket.on('disconnect', function() {
clearInterval(handle);
});
});
Then you can have a client page under public/client.html at http://localhost:3000/client.html to see the session data populated from http://localhost:3000:
<html>
<head>
<script src="/socket.io/socket.io.js" type="text/javascript"></script>
<script type="text/javascript">
tick = io.connect('http://localhost:3000/');
tick.on('data', function (data) {
console.log(data);
});
tick.on('views', function (data) {
document.getElementById('views').innerText = data.views;
});
tick.on('error', function (reason){
console.error('Unable to connect Socket.IO', reason);
});
tick.on('connect', function (){
console.info('successfully established a working and authorized connection');
});
</script>
</head>
<body>
Open the browser console to see tick-tocks!
<p>This session is viewed <b><span id="views"></span></b> times.</p>
</body>