I'm actually working on a little application. I have one server written in C which is listening on the port 5260. In the other side I have a NodeJS client which is listening on the port 7777. A HTML page can be reach via this port. In the HTML page I have a simple button.
When I click on this one a message is sent to my NodeJS server and is written on the terminal. Now I would like to fetch this command and send it to my C server which is still running and waiting for a request.
My client.js :
var http = require('http');
var ejs = require('ejs');
var express=require('express');
var app = express();
app.engine('html', ejs.renderFile);
app.set('/', __dirname);
app.get('/', function(request,response) {
response.render('index.ejs.html');
})
var options = {
host: '192.168.1.154',
path: '/',
port: '5260',
method: 'POST'
};
app.post('/play', function(req, res){
var res = http.request(options);
console.log("START_BG;BG1\n");
});
app.listen(7777);
And my HTML file :
<html>
<head>
<script type="text/javascript" src="client.js"></script>
<script type="text/javascript">
function sendMessage() {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/play', true);
xhr.onload = function() {
console.log(xhr);
};
xhr.send();
}
</script>
</head>
<body>
<button onclick="sendMessage()">VIDEO</button>
</body>
</html>
Well. I see some strange things in your code
1 You're making the post request to 192.168.1.254:5620/play without sending any data on it
2 You're not waiting fro the request to end and blindly print on your console without checking the result. Don't know if its the desired behaviour, but it seems a bit strange
Without more knowledge about the scenario is difficult to suggest an idea.
What is the answer you expect from the remote server?
It's suposed to print something in the (remote) console ?
What it should return via HTTP ?
Anyway I suggest you correct your code as follows:
app.post('/play', function(req, res){
var res = http.request(options, function(response){
// do any checking about response status and/or body if any
console.log("START_BG;BG1\n");
});
});
Related
I try to use Socket.io with my website.
My app.js:
var http = require('http');
var fs = require('fs');
var server = http.createServer(function(req, res) {
fs.readFile('./index.html', 'utf-8', function(error, content) {
res.writeHead(200, {"Content-Type": "text/html"});
res.end(content);
});
});
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
console.log('Connected !');
});
server.listen(8080);
My index.html (with Nginx):
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
</script>
When I'm connect to my website, i have that error in my client console (chrome):
Uncaught SyntaxError: Unexpected token <
Uncaught ReferenceError: io is not defined
What is the problem ?
Thanks !
This is because your HTML file being served to the references a file local to your server, specifically
/socket.io/socket.io.js
. Your app.js file should either include the contents of that file if you want to serve it directly from the file system, or better yet reference a CDN for the client to get the socket.io script file:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.0/socket.io.js"></script>
<script> var socket = io.connect('http://localhost:8080'); </script>
server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
app.use(express.static(__dirname + '/public'));
io.on('connection', function(client) {
console.log('Client connected...');
client.on('join', function(data) {
console.log(data);
io.emit('messages', 'Hello');
});
});
index.html
<script>
var socket = io.connect('http://localhost:7777');
socket.on('connect', function(data) {
socket.emit('join', 'Hello World from client');
});
socket.on('messages', function(data) {
alert(data);
});
</script>
I tried to implement very basic of Socket.io.
However, data sending from client to server is available but from server to client doesn't work.
In the command running server.js, 'Hello World from client' is printed. However, alert window doesn't work in the web browser.(I've also tried to console.log).
How to solve this?
Editted
I've put server.js codes in the app.get('/', function(req, res)){ ... }
Then, it doesn't work. Why it doesn't work in app.get?
Try this, I hope it works:
io.on('connection', function(client) {
console.log('Client connected...');
client.on('join', function(data) {
console.log(data);
io.emit('join', data); //this code sending data from server to client
});
});
If you're just trying to fetch some data with an Ajax call such as /test, then there is no need to use socket.io. That's just a classic request/response.
app.get('/test', function(req, res) {
// collect your data and then send it as a response
res.json(data);
});
If you're just trying to incorporate data into a web page that is requested, then you can use res.render() with the template engine of your choice (ejs, handlebars, pug, etc...). That would typically look like this:
app.get('/test', function(req, res) {
// collect your data and then pass it to res.render() to render your
// your template using that data
res.render('someTemplateName', data);
});
The main thing that socket.io is useful for is "pushing" data from server to client without a client request. So, if something happened on the server that the client was not aware of and the server wanted to tell the client about it, then socket.io would be used for that. The classic example is a chat app. Person A sends a chat message to the server that is addressed to Person B. The server receives that message and then needs to "push" it to Person B. That would be perfect for an already connected socket.io connection because the server can just push the data directly to the Person B client, something the server can't do with request/response (since there is no request from person B).
If you still think you need socket.io, then please describe exactly what you're trying to do with it (step by step what you're trying to send to the client).
socket.on("message",function (reply_data) {
console.log('inside on message functions ')
console.log(reply_data);
})
please change 'messages' to "message" that worked for me
How do I write a script to permanently change a static html file after making an ajax call to the node.js server? Any examples would be greatly appreciated :)
I agree with NikxDa that this is probably not the best solution for you, but this code should do the trick.
/write.js
var http = require('http');
var fs = require('fs');
var url = require('url');
//Lets define a port we want to listen to
const PORT=8080;
function handleRequest(request, response){
var path = url.parse(request.url).pathname;
if(path=="/write"){
fs.appendFile('message.html', 'Node.js!', function (err) {
if (err) throw err;
console.log('It\'s saved!');
});
} else {
fs.readFile('index.html',function (err, data){
response.writeHead(200, {'Content-Type': 'text/html','Content-Length':data.length});
response.write(data);
response.end();
});
}
}
// Create a server.
var server = http.createServer(handleRequest);
server.listen(PORT, function(){
console.log("Server listening on: http://localhost:%s", PORT);
});
/index.html
<!DOCTYPE html>
<head>
<script>
function writeIt()
{
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","http://localhost:8080/write", true);
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
string=xmlhttp.responseText;
document.write(string + ": Saved change to message.html");
}
}
xmlhttp.send();
}
</script>
</head>
<body>
<p>Click the button to send an AJAX request to `write.js`<p>
<br><button onclick="writeIt()">Click Me</button>
</body>
/message.html
Node.js!
Editing the file directly via node would probably be really bad, I do not even know if it is at all possible. I think the better solution is for your Node Server to make the data you want to change accessible and then use jQuery or Angular to update the HTML-File when it is actually loaded.
Another approach would be to use a templating engine like https://github.com/tj/ejs, and then serve the file via Node directly, so you can change the data in the Node-Application itself every time.
I'm trying to use socket.io with koa.js and I was able to connect adding server = require('http').createServer(koa.callback()).listen(port); and io = require('socket.io')(server); at the very bottom of my application but now I want to emit and if possible listen to events from my controller / route. What's the best way to implement this?
I've tried adding io in my koa context like koa.context.io = io and even io.on('connection', function(socket){ koa.context.socket = socket }); but nothing is working.
Thanks in advance guys.
Accessing the socket.io instance in your koa route should not work.
Creating the socket.io instance depends on the application creating a callback function that can be used by the http server.
var server = http.createServer(app.callback());
var io = require('socket.io')(server);
This callback is generated with the help of co and requires that your app is already set up with all the middleware/routes. (see the koa source). Therefore you can't use the socket.io instance (which is created afterwards) in those routes.
Furthermore I think it is not intended to emit socket.io events in your controllers. If you want to send data back to the client that called the controller, you should do it in the response which is generated by that controller. If you want to emit further events at the server you could trigger them from the client by emitting an event that the server will receive. This way you can process the data from the client in the function you pass to socket.on(...) and don't need to implement it in the controller/routes for koa.
Here is an example for the second case, without any koa controller/route.
app.js:
var http = require('http');
var koa = require('koa');
var app = koa();
var send = require('koa-send');
app.use(function* (next) {
if (this.path !== '/') return yield next;
yield send(this, __dirname + '/index.html');
});
var server = http.createServer(app.callback());
var io = require('socket.io')(server);
io.on('connection', function (socket) {
socket.on('click', function (data) {
//process the data here
console.log('client clicked! data:');
console.log(data);
// emit an event
console.log('responding with news');
socket.emit('news', { hello: 'world' });
});
});
var port = process.env.PORT || 3000;
server.listen(port);
console.log ('Listening at port ' + port + ' ...');
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>koa-socket.io</title>
</head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost:3000');
socket.on('news', function (data) {
console.log('received news with data: ');
console.log(data);
});
function myclick () {
console.log("click");
socket.emit('click', { clickdata: 'i clicked the button' });
}
</script>
<button type="button" onclick="myclick();">Click Me and watch console at server and in browser.</button>
</body>
</html>
I realise this is a little late on the uptake, and could be deemed slightly self-serving as I'm going to suggest one of my own modules, but, you're on the right track with appending it to the app, with Koa v2 this is easier as the context is passed right along but with v1 you can tack it onto this, as koa middleware's are bound to the app instance.
Alternatively, I wrote a module to help with this exact use-case, https://github.com/mattstyles/koa-socket, it does just 2 things currently (and probably forever): it appends the socket.io server instance to the context and it allows you to write koa-style middleware for your socket listeners.
I want to send the filepath of a file on my server to the client in order to play it using a media player. How can I retrieve that string on the client side in order to concatenate it in the src attribute of a <video element without using sockets?
Server snippet:
res.set('content-type', 'text/plain');
res.send('/files/download.mp4');
This is how you make a request to the server without any frameworks. "/path_to_page" is the route you set to the page that is supposed to process the request.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path_to_page', true);
xhr.onload = function(e) {
if (this.status == 200) {
console.log(this.responseText); // output will be "/files/download.mp4"
}
};
xhr.send();
}
You might also want to send some params.
var formdata = new FormData();
formdata.append("param_name", "value");
So you might for instance want to send the filename or such.
You just need to change 2 lines from the first code snippet. One would be
xhr.open('POST', '/path_to_page', true); // set to post to send the params
xhr.send(formdata); // send the params
To get the params on the server, if you are using express, they are in req.body.param_name
Which framework are you using??
You can declare base path of your project directory in ajax and the followed by your file.
jQuery.ajax({
type: "GET",
url: "/files/download.mp4",
});
Since you are using express (on node), you could use socket.io:
Server:
var io = require('socket.io').listen(80),
fs = require('fs');
io.sockets.on('connection', function (socket) {
socket.on('download', function(req) {
fs.readFile(req.path, function (err, data) {
if (err) throw err;
socket.emit('video', { video: data });
});
});
});
Client:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
...
// request a download
socket.emit('download', { path: '/files/download.mp4' });
// receive a download
socket.on('video', function (data) {
// do sth with data.video;
});
...
</script>
Edit: didnt notice you didnt want to use sockets. Still it is a viable solution.