Hy, I'm asking because I want to clear my mind about net sockets in Node.js:
I have an easy server that replicates the data received. It looks like this:
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 1337;
net.createServer(function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
sock.write('You told me: ' + data);
});
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
So, if I want to make a really easy html page like this:
<input type="text" name="data" value="" />
<input type="button" value="Send data" onclick="send()" />
<div id="result"></div>
Now I will click on the button and the page sends data to the server, and write the answer into the "result" div. What i need to write or use in the function "send()" (just in order to send the data and receive the answer)? I searched for things like this a lot, but wasn't lucky...
I need to add an http server to the server file maybe?
I recommend you use SockJS module in server and client side. Look this example for client:
var sock = new SockJS('YOUR_SOCKJS_URL');
sock.onopen = function() {
console.log('open');
};
sock.onmessage = function(e) {
console.log('message', e.data);
};
sock.onclose = function() {
console.log('close');
};
function send(){ // this for onclick="send()"
sock.send();
}
For server use Sockjs module. example:
var http = require('http');
var sockjs = require('sockjs');
var echo = sockjs.createServer({ sockjs_url: 'http://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js' });
echo.on('connection', function(conn) {
conn.on('data', function(message) {
conn.write(message);
});
conn.on('close', function() {});
});
var server = http.createServer();
echo.installHandlers(server, {prefix:'/echo'});
server.listen(9999, '0.0.0.0');
Related
I'm using an app.post method in Express like so:
app.post('/race', function(req,res) {
let raceResponse = {
user_name: req.body.userName
}
console.log('Express has received race.');
//Socket.IO
let race = io.of('/race').on('connection', (socket) => {
console.log('A user has entered the race!');
socket.on('racePageReady', function() {
console.log('race page ready recieved');
socket.emit('racePageInfo', raceResponse);
});
socket.on('createRoom', function(roomName) {
socket.join(roomName);
let clients = io.sockets.adapter.rooms[roomName].sockets;
console.log("A room with the name " + roomName + "was created.");
console.log(clients);
socket.emit('roomCreated', clients);
});
socket.on('joinRoom', function(roomName) {
socket.join(roomName);
let clients = io.sockets.adapter.rooms[roomName].sockets;
console.log('A user joined the room with the name: ' + roomName + ". The user's name is " + raceResponse.user_name);
console.log(clients);
socket.emit('roomCreated', clients);
});
});
res.sendFile(path.join(__dirname, '/client/race/index.html'));
}
The page is being sent fine, but the console.log and all the other Socket.IO stuff just doesn't happen. I'm finding this peculiar, because I have a different app.post method that works just fine, all console.logging and Socket.IO business happens. Here's the code:
app.post('/city', function(req,res) {
let cityResponse = {
user_name: req.body.userName
}
console.log('Express has received city.');
//Socket.IO
let city = io.of('/city').on('connection', (socket) => {
socket.id = Math.random();
socket.name = cityResponse.user_name;
SOCKET_LIST[socket.id] = socket; //defined earlier
User.onConnect(socket); //defined earlier
socket.on('cityPageReady', function() {
socket.emit('cityPageInfo', cityResponse);
console.log('city page ready recieved');
});
console.log('A user has connected to the city!');
console.log("Socket: " + socket);
console.log("Socket ID: " + socket.id);
console.log("SOCKET_LIST: ");
console.log(SOCKET_LIST);
socket.on('chat message', function(msg, user) {
console.log('User ' + user + ' sent the message : ' + msg);
socket.emit('chat message', msg, user);
});
});
res.sendFile(path.join(__dirname, '/client/city/index.html'));
});
As far as I can tell, both methods look pretty much the same, except for the Socket.IO stuff in the middle. I'm fairly certain that the io.of method is correct, as it's working for the City page, but not the race.
The only other difference is the way that the two pages are accessed. The City page is accessed through a HTML form with an action attribute, whereas the Race page is accessed through a HTML link (on the City page) with a href attribute.
Both methods are shown below:
CITY
<form id="cityForm" action="http://localhost:4000/city" method="POST">
User name: <input type="text" name="userName">
button type="submit" id="formSubmit">Submit</button>
</form>
RACE
<div><a href="http://localhost:4000/race"></div>
Can anyone see why this peculiar behaviour is occuring? If any other information is needed please let me know so that I can include it.
When clicking an on HTML link, the browser does a GET HTML request. When you submit a Form (with method="POST"), the browser does a POST request.
When using app.post(), you tell express to listen for POST requests. If you want express to listen for GET requests, you should use app.get()
Is there someone can help me or give me a tutorial on how I can display the base64 string from Node.Js to JSP/HTML img tag?
Im passing base64 string to this Node.Js server from Java application.
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
var cl = require('./client.js');
net.createServer(function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
sock.on('data', function(data) {
sock.write(data);
var client = new cl.client(data);
});
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
process.on('uncaughtException', function (err) {
console.error(err.stack);
console.log("Node NOT Exiting...");
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
Does the Base64 string start with data:image/jpeg;base64(the type may be different).
If so, you can set the src attribute of img tag with it.
<img src="data:image/jpeg;base64XXXXXXXXX">
If the base64 string that you are passing already has data:image/[image type];base64 prefix then you can just set it in the image source you don't need to do anything special.
Or just have a method to check it and add the prefix if you don't have it.
function setBase64ToImage(baseString){
// data:image/[image type];base64
if(baseString.substring(0,4) != "data"){
baseString = "data:image/png;base64," + baseString;
}
return baseString;
}
and in your HTML img src tag
<img src=setBase64ToImage(data)>
If your question is how to pass data from node.js to the html file then you should use a template like ejs or something to make it easy.
https://github.com/tj/ejs or look at this question which anwers how to pass data from node to html.
Variables between Node.js Server and Client
I am atempting to build a chatroom with NodeJS and Socket.io and I have gotten so far as to get the users input and send it to the Node server but that's all I want to be able to display it up in a div
Client-side script
var socket = io();
$('form').submit(function(e) {
e.preventDefault();
// gets the value from the message text feild and sets it as the message var
var message = {
text: $('#chat-box-div-txtinpt').val()
}
if (message.text.trim().length !== 0) {
socket.emit('chat-message', message);
}
$('#chat-box-div-txtinpt').focus();
document.getElementById('chat-box-div-txtinpt').value='';
});
Server-side script
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res) {
res.sendfile('index.html');
});
http.listen(3000, function() {
console.log('listening on *:3000');
});
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconected');
});
socket.on('chat-message', function (message) {
console.log('message: ' + message.text);
});
});
Here is the site
It appears you're using jQuery, so for this line: document.getElementById('chat-box-div-txtinpt').value=''; you could just do $('#chat-box-div-txtinpt').val('');
to answer your question: you could just do $('#chatlog-display-div').append(message.text)
Your code would end up looking something like this
$('form').submit(function(e) {
e.preventDefault();
//gets the value from the message text feild and sets it as the message var
var message = {
text : $('#chat-box-div-txtinpt').val()
}
if (message.text.trim().length !== 0) {
socket.emit('chat-message', message);
//append the message to the chatlog-display-div
$('#chatlog-display-div').append(message.text);
}
//clear the value of the txtinput after you focus it.
$('#chat-box-div-txtinpt').focus().val('');
});
please mark as accepted answer if you feel this adequately solves the issue.
To send messages to everyone from the server use emit() from io
on server
socket.on('chat-message', function (message) {
console.log('message : ' + message.text);
io.emit("chat-message",message);
});
on client
socket.on('chat-message',function(message){
//add message to the chat window
});
If you do not want the person sending the message to get the chat-message emit then use broadcast.emit() from the socket that sent it
//server
socket.on('chat-message', function (message) {
console.log('message : ' + message.text);
//excludes "socket" from getting the emit
socket.broadcast.emit("chat-message",message);
});
To actually put the message in the div just use any of jQuery's various methods html()/text()/append()
//client
socket.on('chat-message', function (message) {
jQuery(".chat-window").append('<div>'+message.text+'</div>');
});
You could simple .append the text to "chatlog-display-div" with a templet if you use ES6 could be something like
$('form').submit(function(e) {
e.preventDefault();
//gets the value from the message text feild and sets it as the message var
var message = {
text : $('#chat-box-div-txtinpt').val()
}
if (message.text.trim().length !== 0) {
socket.emit('chat-message', message);
document.getElementById('chatlog-display-div').append('<divclass="message-style" > ${message.text}</div>')
}
$('#chat-box-div-txtinpt').focus();
document.getElementById('chat-box-div-txtinpt').value='';
});
I wrote a piece of code that allows me search for all tweets hash tagged hello.
var stream = T.stream('statuses/filter', { track: 'hello', stall_warnings: true });
var counter = 0;
if (stream) {
console.log('connected!');
};
stream.on('tweet', function (tweet) {
console.log('tweet: '+ tweet.text);
console.log('by:' + ' #' + tweet.user.screen_name);
console.log('date:'+ ' ' + tweet.created_at + ' | ' + counter);
counter++;
});
How do I go about redirecting this so that I can create a web page that looks like a Twitter stream data, or something of the sort? Maybe using AngularJS.
You will have to create a web server first, try express.
then you can use something like sockets.io to communicate from the server to your client web page.
then on the webpage you must handle the messages to display them (angular, or maybe just jQuery) - basically on tweet you will send a message from your server to the client web page through socket.io, then your dront end javascript will get the message, parse it and decide how to display it.
Have a look at Sails.js, it's basically express with sockets integrated and a few more things
edit
say you export your server in server.js,
var http = require('./server.js');
var io = require('socket.io')(http);
stream.on('tweet', function (tweet) {
io.sockets.emit("new tweet", {
text: tweet.text,
by: tweet.user.screen_name,
date: tweet.created_at,
counter: counter++;
});
});
require('socket.io')(http) starts the "socket manager" on your server (and also publishes the js client side code for it), so clients can connect to your server through sockets.
io.sockets.emit will send a message to all connected clients.
on your web page you must have something like this
<div id="tweets"></div>
<script src="/your/js/jquery.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on("new tweet", function(tweet) {
$('#tweets').append('tweet: ' + tweet.text + '<br>');
$('#tweets').append('by:' + ' #' + tweet.by + '<br>');
$('#tweets').append('date:'+ ' ' + tweet.date + ' | ' + tweet.counter + '<br>');
});
</script>
the library /socket.io/socket.io.js was published by that require('socket.io')(http) from earlier, so we can use it on our clients.
the call io() basically connects to the server, and returns a handle to that connection (socket), we use that to receive all messages from the server, and on each message you can write the contents to the page anyway you want.
With socket.io you can broadcast events from the server to the client, in this case you could do something like this :
stream.on('tweet', function (tweet) {
io.sockets.emit("new tweet", tweet);
counter++;
});
And you could receive that event on the client-side like this :
var socket = io();
socket.on("new tweet", function(tweet){
//Do something with the tweet
});
This is a very basic and generic example, for more information you can look at the official documentation here.
I've created client and server of node with socket.io. server is executing 4 get requests of news feed and fetched the data. These data is sent to the client with socket.io.
client is displaying news feed on the occurrence of specific socket.io event.
This works well for once. Here is the code and working fiddle
server.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
, redis = require("redis");
var http = require("http");
// initialize the container for our data
var data = "";
var nfs = [
"http://economictimes.feedsportal.com/c/33041/f/534037/index.rss",
"http://www.timesonline.co.uk/tol/feeds/rss/uknews.xml",
"http://www.independent.co.uk/news/business/rss",
"http://www.dailymail.co.uk/money/index.rss"
];
//setInterval(function() {
for(var i=0; i<nfs.length; i++){
//console.log(nfs[i]);
http.get(nfs[i], function (http_res) {
// this event fires many times, each time collecting another piece of the response
http_res.on("data", function (chunk) {
// append this chunk to our growing `data` var
data += chunk;
});
// this event fires *one* time, after all the `data` events/chunks have been gathered
http_res.on("end", function () {
// you can use res.send instead of console.log to output via express
console.log("data received");
});
});
}
//}, 30000);
app.listen(8080);
function handler (req, res) {
fs.readFile(__dirname + '/client.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function (socket) {
//setInterval(function() {
socket.emit('news', data);
/*socket.on('my other event', function (data) {
console.log(data);
});*/
//}, 5000);
});
client.html
<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.2.1.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
//socket io client
var socket = io.connect('http://localhost:8080');
//on connetion, updates connection state and sends subscribe request
socket.on('connect', function(data){
setStatus('connected');
socket.emit('subscribe', {channel:'notif'});
});
//when reconnection is attempted, updates status
socket.on('reconnecting', function(data){
setStatus('reconnecting');
});
//on new message adds a new message to display
socket.on('news', function (data) {
console.log(data);
//socket.emit('my other event', { my: 'data' });
addMessage(data);
});
/*socket.on('news', function (data) {
debugger;
socket.emit('my other event', { my: 'data' }
var msg = "";
if (data) {
msg = data;
}
addMessage(msg);
});*/
//updates status to the status div
function setStatus(msg) {
$('#status').html('Connection Status : ' + msg);
}
//adds message to messages div
function addMessage(msg) {
//debugger;
var $xml = $(msg);
var html = '';
$xml.find("item").each(function() {
var $item = $(this);
html += '<li>' +
'<h3><a href ="' + $item.find("link").text() + '" target="_new">' +
$item.find("title").text() + '</a></h3> ' +
'<p>' + $item.find("description").text() + '</p>' +
// '<p>' + $item.attr("c:date") + '</p>' +
'</li>';
});
$('#result').prepend(html);
}
</script>
</head>
<body>
<div id="status"></div><br><br>
<ul id="result"></ul>
</body>
</html>
What I understand about socket.io is that we don't need long server polling and so how do server come to know that news is added to the respected news feed.
How do I update the client with newly added news when news is added to the news feed rss ???
Update
Ok so from all the responses I get the point that it is not possible for socket.io to know that new entry has been added. So, how do I know (which tools/libraries do require to know that new entry has beed added and update the client as well) ???
Retrieving the messages from the news feeds are completely independent of socket.io unless the news feeds implement sockets on their end and your server becomes their client. So you will have to continue to poll them with http requests to know whether they have updated data.
In order to notify your clients of the update you would just emit the news event. Presumably you would have logic on the server to make sure you are only sending events which have not previously be sent.
There is no way for "node" to know when a new entry is added to the news feed. You will have to poll the news service like you are doing now. This really has nothing to do with Node or Socket.io unless I completely misunderstand what you are asking.