I'm using node.js and socket.io for a simple app. My browser is receiving data from server nicely but server not receiving from client(browser). May be the event listener for client_data not working. Here is the server:
var http = require("http");
var url = require("url");
var io = require('socket.io');
function start(route) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
route(pathname, response);
}
var server = http.createServer(onRequest);
server.listen(8888);
var server_io = io.listen(server);
server_io.on('connection', function(socket){
//send data to client
setInterval(function(){
socket.emit('date', {'date': new Date()});
}, 1000);
});
//recieve client data
server_io.on('client_data', function(data){ //May be it is not listening
process.stdout.write(data.letter); // not working
//console.log(data.letter); not working
});
console.log("Server has started.");
}
exports.start = start;
Client code:
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<script>
var socket = io.connect();
socket.on('date', function(data){
document.getElementById("date").innerHTML = data.date;
});
function sendKey(e){
socket.emit('client_data', {'letter': String.fromCharCode(e.charCode)});
}
</script>
<div id="date">This is our socket.html file</div>
<textarea id="text" onKeyPress="sendKey(event)"></textarea>
</body>
</html>
What is the problem with my server code?
This error occurs because .on('client_data') must be binded to socket, not server_io. The code may look like the following:
server_io.on('connection', function(socket){
setInterval(function(){
socket.emit('date', {'date': new Date()});
}, 1000);
socket.on('client_data', function(data){
process.stdout.write(data.letter);
});
});
server_io only recieves connection events. The client_data event sent from the client is heard by the socket object passed into the connection callback, not the server_io object.
You need to use socket.on("client_data", ...); and move that code into your connection callback.
That socket object is connected to a particular client web page instance, and it recieves messages only sent by that page. Each time a new client page connects, a new socket object is created and passed as an argument into the connection handler function.
Related
I'm trying to come to terms with how WebSockets work in Node.js but I'm having some trouble with sending a message.
I have my WebSocket server configured as follows (index.js)
var ws = require("ws");
var wsserver = new ws.Server ({
server: httpserver,
port: 3030
});
wsserver.on (
"connection", function connection(connection) {
console.log("connection");
}
);
wsserver.on (
"open", function open(open) {
console.log("open");
}
);
wsserver.on (
"message", function message(message) {
console.log("message");
}
);
This seems to be working ok because I can establish the connection using
var wscon = new WebSocket("ws://192.168.20.88:3030");
Which then gives me the connection output on the server. If I try to use send though nothing seems to happen and no error messages
wscon.onopen = function(open) {
wscon.send("test message");
}
I must be missing something but I don't know what
I might have an answer for this but I'm not entirely sure just yet, I'm going to put this here just in case.
I think the problem is that the message listener is added to the wrong object (the server object), I tried to add the message listener to the connection object passed to the server and it seems to be working but I'm not 100% sure why
wsserver.on (
"connection", function connection(connection) {
console.log("connection");
connection.on (
"message", function message(message) {
console.log("message : " + message);
}
);
}
);
Which dependency works for me?
I have been using socketIO for a while now and it works perfectly for Node.JS API's / servers. There are millions of tutorials online for this framework and I'll tell you one them.
How to install?
If you use NPM as your package manager in Node.JS just down it with the following command:
npm install --save socket.io
In case you're using yarn you can install socketIO as following:
yarn add socket.io
Setup the socket server:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
// Used for serving the HTML page (if used)
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
// Listen for new connections
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Now in index.html I add the following snippet before the :
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
In your front-end you are able to fire of an event via the socket by calling the following function / code:
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
});
</script>
In our case we emitted an event called chat message. So in order to receive the value send over the socket connection we call the following code in our backend / api:
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
});
});
and that is basically how you use socket with the library SocketIO. Hope this helped fixing your issue!
I'm developping simple app with nodejs and socket.io.
I created two channels and I want my client connect one of channels when click on button. The problem is I don't get response from server
This is my code :
// SERVER side
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var nameSpaceWeek = io.of('/week');
var nameSpaceDay = io.of('/day');
app.get('/', function(req, res){
res.sendfile('MDC.html');
});
io.on('connection', function(socket){
console.log("User = " + socket.id)
});
nameSpaceDay.on('connection', function(socket){
console.log('someone connected on namespace day');
nameSpaceDay.emit('hiDay', 'Hello everyone on namespace day!');
});
nameSpaceWeek.on('connection', function(socket){
console.log('someone connected on namespace week');
nameSpaceDay.emit('hiWeek', 'Hello everyone on namespace week!');
});
http.listen(3000, function(){
console.log('listening on localhost:3000');
});
// CLIENT SIDE
<!DOCTYPE html>
<html>
<head><title>Hello world</title></head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
function setDay(){
console.log("setDay");
socket = io.connect('/day');
console.log(socket)
}
socket.on('hiDay',function(data){
console.log("hiDay")
console.log("data = ." + data + ".")
document.getElementById('message-container').innerHTML = 'Update day'
console.log("data = ." + data + ".")
});
function setWeek(){
console.log("setWeek");
socket = io.connect('/week');
console.log(socket)
}
socket.on('hiWeek',function(data){
console.log("hiWeek")
document.getElementById('message-container').innerHTML = 'Update Week'
//document.getElementById('message-container').innerHTML = data
console.log(data)
});
</script>
<body>
<div id="message-container"></div>
<div id="error-container"></div>
<button type="button" name="button" onclick="setWeek()">Week</button>
<button type="button" name="button" onclick="setDay()">Day</button>
</body>
In my client, I created two button and when I click on one I want change socket namespace
When you call setDay() or setWeek(), you are creating a whole new socket.io connection and thus overwriting your previous socket variable. The socket.on(hiDay, ...) and socket.on('hiWeek', ...) handlers you have are ONLY on the first socket you created, not on the newly created sockets, thus you never see the messages on those.
To fix, add those message handlers only to the right socket after you've connected to that namespace.
function setWeek() {
// close previous socket.io connection
socket.close();
// make new connection to new namespace
console.log("setWeek");
socket = io.connect('/week');
console.log(socket)
// add event handler for new socket
socket.on('hiWeek',function(data){
console.log("hiWeek")
document.getElementById('message-container').innerHTML = 'Update Week'
console.log(data)
});
}
Then, do the same thing for the setDay() function.
And, as shown here you probably want to disconnect the previous connection when changing namespaces too so you don't necessarily leave connections that you aren't using any more.
FYI, you also had a typo where this:
nameSpaceDay.emit('hiWeek', 'Hello everyone on namespace week!');
should have been this:
nameSpaceWeek.emit('hiWeek', 'Hello everyone on namespace week!');
Final, tested and working code is this:
<!DOCTYPE html>
<html>
<head><title>Hello world</title></head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
function setDay(){
socket.close();
console.log("setDay");
socket = io.connect('/day');
socket.on('hiDay',function(data){
console.log("hiDay")
document.getElementById('message-container').innerHTML = 'Update day';
console.log(data);
});
}
function setWeek() {
// close previous socket.io connection
socket.close();
// make new connection to new namespace
console.log("setWeek");
socket = io.connect('/week');
// add event handler for new socket
socket.on('hiWeek',function(data){
console.log("hiWeek");
document.getElementById('message-container').innerHTML = 'Update Week';
console.log(data);
});
}
</script>
<body>
<div id="message-container"></div>
<div id="error-container"></div>
<button type="button" name="button" onclick="setWeek()">Week</button>
<button type="button" name="button" onclick="setDay()">Day</button>
</body>
And server code:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var path = require('path');
var nameSpaceWeek = io.of('/week');
var nameSpaceDay = io.of('/day');
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, 'socket-io-namespace.html'));
});
io.on('connection', function(socket){
console.log("User = " + socket.id)
});
nameSpaceDay.on('connection', function(socket){
console.log('someone connected on namespace day');
nameSpaceDay.emit('hiDay', 'Hello everyone on namespace day!');
});
nameSpaceWeek.on('connection', function(socket){
console.log('someone connected on namespace week');
nameSpaceWeek.emit('hiWeek', 'Hello everyone on namespace week!');
});
http.listen(3000, function(){
console.log('listening on localhost:3000');
});
If you create a connect(ns) function you can reconstruct the socket event listener when the namespace changes. The following should work:
<script>
var connect = function (ns) {
return io.connect(ns, {
query: 'ns=' + ns,
resource: "socket.io"
}).on('hiWeek', function (data) {
console.log("hiWeek")
document.getElementById('message-container').innerHTML = 'Update Week'
//document.getElementById('message-container').innerHTML = data
console.log(data)
}).on('hiDay', function (data) {
console.log("hiDay")
console.log("data = ." + data + ".")
document.getElementById('message-container').innerHTML = 'Update day'
console.log("data = ." + data + ".")
});
}
var socket = io();
function setDay() {
console.log("setDay");
socket = connect('/day');
console.log(socket);
}
function setWeek() {
console.log("setWeek");
socket = connect('/week');
console.log(socket);
}
</script>
I have created my first application of Nodejs. I am using socket.io and express. I tried this tutorial: https://socket.io/get-started/chat/ and I find emit is what I might need not sure.
My application shows stock tickers, I am using API's, I have url like: https://quotes.example.com/v1/file.json/johndoe?&_token=tokenumber
All the users who open http://example.com/live page, I would like to push or emit stock tickers to this page. How do I best achieve this? I get the idea of live page needs to be a channel to which all user would subscribe and I am pushing data to it.
I have never worked on real-time apps before, all suggestions are welcomed.
Edited
Front-end code
<!doctype html>
<html>
<head>
<title>Live Stock Quotes App</title>
<style>
body { font: 26px Helvetica, Arial; font-weight:bold;}
#livequotes { text-align: center;}
</style>
</head>
<body>
<p id="livequotes"></p>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io('/channel1');
socket.on('live-quote', function(msg){
$('#livequotes').text(msg);
});
});
</script>
</body>
</html>
server-side code
var app = require('express')();
var http = require('http').Server(app);
var httpk = require('http');
var io = require('socket.io')(http);
var nsp = io.of('/channel1');
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
nsp.on('connection', function(socket){
nsp.emit('live-quote', 'Welcome User!');
//Make a http call
function test()
{
httpk.get("url-to-api", function(res) {
var body = ''; // Will contain the final response
res.on('data', function(data){
body += data;
});
res.on('end', function() {
var parsed = JSON.parse(body);
console.log(parsed.johndoe.bid_price);
return parsed.johndoe.bid_price;
});
});
}
setInterval(test,500);
socket.on('disconnect', function(){
console.log('1 user disconnected');
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Above code I have put as you suggested. Now, I wanted to do add something like:
setInterval(test,500);
function test (){
http.get("url-for-api", function(res) {
var body = ''; // Will contain the final response
res.on('data', function(data){
body += data;
});
// After the response is completed, parse it and log it to the console
res.on('end', function() {
var parsed = JSON.parse(body);
console.log(parsed.johndoe.bid_price);
data = parsed.johndoe.ask_price;
});
})
// If any error has occured, log error to console
.on('error', function(e) {
console.log("Got error: " + e.message);
});
}
It's not entirely clear exactly what you're asking, but I'll take a stab at it.
If you want to be able to "push" new stock updates to a client using socket.io, then the usual way you would do that is a client would make a socket.io connection to your server and then your server can issue updates to all connected clients by doing an io.emit(msg, data) on the server. That will send that message and data to all connected clients.
If you want these updates to be sent to a web page, then you put Javascript in that web page that makes the socket.io connect to your server and then listens on that socket for the appropriate messages from the server. When it receives the messages from the server, it can then insert them into the page in whatever fashion you find appropriate.
This client code from the socket.io doc pages would be typical of the client-side:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('udpate', function (data) {
console.log(data);
// do something with the data here (like insert it into the web page)
});
</script>
If you have to tell the server which stock updates you're interested in so only those updates are sent to the client page, then you will need to do more work on both client and server to allow the server to keep track of which connection is interested in which updates and only send to the right connections. You could use socket.io rooms to help manage that. A client connection requests to join a room for a given stock and then stock updates for a particular stock are sent only to the clients in that corresponding room.
Trying to communicate TCP server with HTTP server
My TCP port is 4040 and HTTP port is 3000
I am working on passing data received on TCP server to HTTP server
Data received on TCP port is showing on console window and I am trying to pass this data to HTTP by storing data in global var so that I can display it on the webpage.
Thanks :)
server code:
enter code here var http = require('http').createServer(httpHandler);
var net = require('net');
var app = require('express')(); <!-- These are mandatory variables -->
var http = require('http').Server(app);
var io = require('socket.io')(http);
var sockets = [];
var HOST = 'localhost';
var PORT = 4040;
global.MYVAR = "Hello world";
global.MYVAR2 = "Hello world";
var server = net.createServer();
server.listen(PORT, HOST);
// Keep track of the chat clients
var clients = [];
/**
* http server
*/
function httpHandler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
app.get('/', function(req, res){ <!-- This sends the html file -->
//send the index.html file for all requests
res.sendFile(__dirname + '/index.html');
});
http.listen(3000, function(){ <!-- Tells the HTTP server which port to use -->
console.log('listening for HTTP on *:3000'); <!-- Outputs text to the console -->
console.log('listening for TCP on port ' + PORT);
});
<!-- everything below this line is actual commands for the actual app -->
io.on('connection', function(socket) // Opens the socket
{
socket.on('checkbox1', function(msg){ // Creates an event
console.log(msg); // displays the message in the console
MYVAR = msg; // Sets the global variable to be the contents of the message recieved
for (var i = 0; i < sockets.length; i++) {
if(sockets[i]) {
sockets[i].write(MYVAR, 'utf-8');
}
}
});
});
server.on('connection', function(socket){ // Opens the socket for the TCP connection
sockets.push(socket);
socket.write(MYVAR, 'utf-8');
// Handle incoming messages from clients.
socket.on('data', function (data) {
broadcast(socket.name + "> " + data, socket);
});
// Send a message to all clients
function broadcast(message, sender) {
MYVAR2 = message;
console.log(MYVAR2);
socket.broadcast.emit('updateHeader',MYVAR2); // GETTING ERROR HERE
}
}).listen(PORT, HOST);
index.html code:
<!doctype html>
<html>
<head>
<title>Socket IO Test</title>
</head>
<body>
<h1 id="h1">Hello World</h1>
<form action="">
<input type='checkbox' onclick='checkbox1(this);'>Checkbox1</label>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
var number = 0;
$(document).ready(function(){
socket.on('updateHeader',function(data){
console.log('updateHeader called');
document.getElementById('h1').innerHTML = data;
});
});
function checkbox1(cb) {
socket.emit('checkbox1', 'checkbox 1 = ' + cb.checked);
return false;
}
</script>
The problem is you're trying to use socket.io broadcast in a net.Socket which of course doesn't have that property.
server.on('connection', function(socket){ /* ... */ }
When a new TCP stream is established. socket is an object of type
net.Socket. Usually users will not want to access this event. In
particular, the socket will not emit 'readable' events because of how
the protocol parser attaches to the socket. The socket can also be
accessed at request.connection.
I don't know exactly what you're trying to achieve, but you can use io.emit if you want to send message to all clients.
function broadcast(message, sender) {
MYVAR2 = message;
//This will emit 'updateHeader' to all socket.io connected sockets
io.emit('updateHeader', MYVAR2);
//The 'socket' you were using here was a net.Socket not a socket.io one.
}
function broadcast(message, sender) {
MYVAR2 = message;
console.log(MYVAR2);
sender.broadcast.emit('updateHeader',MYVAR2); //Replace socket by sender here
}
I thought that socket.io would allow me to implement a websocket server. I have this very simple code:
// Require HTTP module (to start server) and Socket.IO
var http = require('http'), io = require('socket.io');
// start at port 8888
var server = http.createServer(function(req, res) {
res.writeHead(200,{'Content-Type': 'text\html'});
res.end('<h1>Welcome to the Notification Server</h1>');
});
server.listen(8888);
// Create Socket.io obj/pass to server
var socket = io.listen(server);
socket.on('connection', function(client) {
console.log('Successful Websocket connection!');
client.on('message', function(event) {
console.log("Received message from client", event);
});
client.on('disconnect', function() {
console.log('Client has disconnected');
});
});
I've tried a few different test clients all of which generate this message on the server: debug - destroying non-socket.io upgrade
One such client attempt has some code like this:
<html>
<script type="text/javascript">
<!---
window.WebSocket = window.WebSocket || window.MozWebSocket;
var ws = new WebSocket("ws://dev.ourserver.com:8888");
ws.onopen = function() {
alert("Connected");
}
ws.onerror = function(error) {
alert("Error:"+error);
}
// -->
</script>
<body>
</body>
</html>
As soon as we load the page I get the debug message on the server.
I thought the point of this library was to support the websocket protocol and any client supporting websockets would be able to connect.
If I interpret the message literally it seems to indicate that server.io has detected that it is connecting to a "non socket.io" client. Does this mean that there is no way for me to connect to this server without using socket.io in the client?