I have run my nodeServer and Client sucessfully. But I want to connect its server to a proxy.
Here is the node client:
<html>
<head>
<script src="http://localhost:8000/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
<script>
var name = '';
var socket = io.connect('http://localhost:8000');
// at document read (runs only ones).
$(document).ready(function(){
// on click of the button (jquery thing)
// the things inside this clause happen only when
// the button is clicked.
$("button").click(function(){
// just some simple logging
$("p#log").html('sent message: ' + $("input#msg").val());
// send message on inputbox to server
socket.emit('chat', $("input#msg").val() );
// the server will recieve the message,
// then maybe do some processing, then it will
// broadcast it again. however, it will not
// send it to the original sender. the sender
// will be the browser that sends the msg.
// other browsers listening to the server will
// recieve the emitted message. therefore we will
// need to manually print this msg for the sender.
$("p#data_recieved").append("<br />\r\n" + name + ': ' + $("input#msg").val());
// then we empty the text on the input box.
$("input#msg").val('');
});
// ask for the name of the user, ask again if no name.
while (name == '') {
name = prompt("What's your name?","");
}
// send the name to the server, and the server's
// register wait will recieve this.
socket.emit('register', name );
});
// listen for chat event and recieve data
socket.on('chat', function (data) {
// print data (jquery thing)
$("p#data_recieved").append("<br />\r\n" + data.msgr + ': ' + data.msg);
// we log this event for fun :D
$("p#log").html('got message: ' + data.msg);
});
</script>
</head>
<body>
<input type="text" id="msg"></input><button>Click me</button>
<p id="log"></p>
<p id="data_recieved"></p>
</body>
</html>
Here is Server:
var check="check";
var io = require('socket.io').listen(8000);
// open the socket connection
io.sockets.on('connection', function (socket) {
// listen for the chat even. and will recieve
// data from the sender.
console.log('hello nahid');
socket.on('chat', function (data) {
// default value of the name of the sender.
var sender = 'unregistered';
check=sender;
// get the name of the sender
socket.get('nickname', function (err, name) {
console.log('Chat message by ', name);
console.log('error ', err);
sender = name;
});
// broadcast data recieved from the sender
// to others who are connected, but not
// from the original sender.
socket.broadcast.emit('chat', {
msg : data,
msgr : sender
});
});
// listen for user registrations
// then set the socket nickname to
socket.on('register', function (name) {
// make a nickname paramater for this socket
// and then set its value to the name recieved
// from the register even above. and then run
// the function that follows inside it.
socket.set('nickname', name, function () {
// this kind of emit will send to all! :D
io.sockets.emit('chat', {
msg : "naay nag apil2! si " + name + '!',
msgr : "mr. server"
});
});
});
});
They work well together. Now I want to have included server file into another html client like this:
<script type="text/javascript" src="nodeServer.js"></script>
In order to access variables in nodeServer.js. But The error "Uncaught ReferenceError: require is not defined "
What can I do to solve this and also I have this line code :
such that it knows what socket.io syntax is. But the error exists.
What should I do to make my html file know socket.io.js.
EDIT:
The last comment on the checked answer is what solved my issue. Thanks to #Houseman.
I'm pretty sure you can't just throw a Node.js file into a html DOM and expect it to work. Node.js files are run by Node.js, not by client-side html javascript.
This line <script src="http://localhost:8000/socket.io/socket.io.js"></script> is sufficient for loading the io object into your DOM, and make it accessible through javascript.
Remove this line:
<script type="text/javascript" src="nodeServer.js"></script>
, and you should be fine, if your server is running on port 8000. Your server code, however, doesn't seem to have the necessary components to actually run.
EDIT:
If you want to pass variables from your client to your server, or the other way around, use sockets, just like you're already doing.
Related
I'm trying to pass data from c# using console application to webpage using socket.io in real time
here is my c# code:
static void Main(string[] args)
{
int i = 0;
while(true)
{
//String data = Console.ReadLine();
String data = i.ToString();
if(data.Equals("exit", StringComparison.OrdinalIgnoreCase)) break; //If the user types "exit" then quit the program
SendData("127.0.0.1", 41181, data); //Send data to that host address, on that port, with this 'data' to be sent
//Note the 41181 port is the same as the one we used in server.bind() in the Javascript file.
System.Threading.Thread.Sleep(50); //Sleep for 50ms
i++;
}
}
public static void SendData(string host, int destPort, string data)
{
IPAddress dest = Dns.GetHostAddresses(host)[0]; //Get the destination IP Address
IPEndPoint ePoint = new IPEndPoint(dest, destPort);
byte[] outBuffer = Encoding.ASCII.GetBytes(data); //Convert the data to a byte array
Socket mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //Create a socket using the same protocols as in the Javascript file (Dgram and Udp)
mySocket.SendTo(outBuffer, ePoint); //Send the data to the socket
mySocket.Close(); //Socket use over, time to close it
}
this is app.js
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
var fs = require('fs');
var mySocket = 0;
app.listen(3000); //Which port are we going to listen to?
function handler (req, res) {
fs.readFile(__dirname + '/index.html', //Load and display outputs to the index.html file
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) {
console.log('Webpage connected'); //Confirmation that the socket has connection to the webpage
mySocket = socket;
});
//UDP server on 41181
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
console.log("Broadcasting Message: " + msg); //Display the message coming from the terminal to the command line for debugging
if (mySocket != 0) {
mySocket.emit('field', "" + msg);
mySocket.broadcast.emit('field', "" + msg); //Display the message from the terminal to the webpage
}
});
server.on("listening", function () {
var address = server.address(); //IPAddress of the server
console.log("UDP server listening to " + address.address + ":" + address.port);
});
server.bind(41181);
finally this is index.html
<html>
<head>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
</head>
<body>
<script>
var socket = io();
socket.on('field', function (data) {
$("#field").html(data);
});
</script>
Data from C#: <div id="field"></div>
</body>
</html>
I used this article to implement it, everything, seems work fine for example when I send data to console of node.js it display it but as soon as I run the page (localhost:3000) after several printing "webpage connected" it shows this error in my console:
nodemon app crashed - waiting for file changes
can someone give me a solution?
this my result picture
Error may occure on a different levels. I see that you are not listenning socket errors, both for server and io.
Both of them are based on EventEmiter approach, so both have error event to listen.
Try to listen all possible error places, this will give you additional infromation on why your app crashed.
server.on("error", err => console.error("server error occured", err));
io.on("error", err => console.error("io error occured", err));
Update
Replace in index.html script loading for socket.io with this.
<script src="/socket.io/socket.io.js"></script>.
Then, all re-connection issues should gone. I'm not pretty sure how it is working.
I am using Node.JS with Express. The following line fails, and I need help fixing it.
var routines = require("myJsRoutines.js");
When I run index.html and click MenuItem, I get the first alert, but not the second one.
I have both files in the same directory. Thanks
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
MenuItem
<script>function myMenuFunc(level) {
alert("myMenuFunc1:" + level);
var routines = require("myJsRoutines.js");
alert("myMenuFunc:2" + level);
routines.processClick(level);
alert("myMenuFunc:3" + level);
}</script>
</body>
</html>
myJsRoutines.js:
exports.processClick = function processClick (param1) {
console.log(param1)
}
Script in <script> tags only runs on the client, and script on the server never directly handles DOM events like clicks. There is no magical event wireup - you need to make them interact.
Assuming folder structure from http://expressjs.com/en/starter/generator.html
Updated module code, in /modules/myJsRoutines.js...
var myJsRoutines = (function () {
var multiplier = 2;
return {
processLevel: function (level, callback) {
console.log('processLevel:', level); // CLI or /logs/express_output.log
// validation
if (!level) {
// error is usually first param in node callback; null for success
callback('level is missing or 0');
return; // bail out
}
// processing
var result = level * multiplier;
// could return result, but need callback if code reads from file/db
callback(null, result);
}
};
}()); // function executed so myJsRoutines is an object
module.exports = myJsRoutines;
In /app.js, load your module and add a get method...
var myJsRoutines = require('./modules/myJsRoutines');
app.get('/test', function (req, res) {
var level = parseInt(req.query.level) || 0;
console.log('server level:', level);
myJsRoutines.processLevel(level, function (err, result) {
if (err) {
res.status(500);
return res.send(err);
}
res.send('result ' + (result || '') + ' from the server');
});
});
In /public/index.html, add client script to make an HTTP request to the get method...
<a class="test" href="#" data-level="1">Test Level 1</a>
<a class="test" href="#" data-level="2">Test Level 2</a>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script>
$(function(){ // jQuery DOM ready
$('.test').click(function () { // click event for <a class="test">
var level = $(this).data('level'); // from data-level="N"
var url = '/test?level=' + escape(level);
console.log('client url:', url);
// HTTP GET http://localhost:3000/test?level=
$.get(url, function (data) {
console.log('client data:', data); // browser console
});
return false; // don't navigate to href="#"
});
});
</script>
...start the server from the command line...
npm start
...open http://localhost:3000/ in your browser, Ctrl+Shift+i to open the browser console, and click the links.
Run from a node server..var routines = require("myJsRoutines.js"); in the server.js file and Just call a javascript onclick function..and post parameters..for posting parameters..you'll be needing Ajax...and console log the data in node..or After sending the data to the node server..run the function in node server.
Code snippet for calling the function from a href..
and
`MenuItem
<script type="text/javascript">
function myMenuFunc('Level 1') {
// return true or false, depending on whether you want to allow the `href` property to follow through or not
}
`
This line:
var routines = require("myJsRoutines.js");
fails because the require statement is a nodejs function. It does not work with the browser nor does it work with javscript natively. It is defined in nodejs to load modules. To see this
go to your command line and run this
> node
> typeof require
'function'
go to your browser console; firefox - press Ctrl + K
>> typeof require
"undefined"
To achieve your aim, there are two options that come to my mind
// Assumed Express server running on localhost:80
var express = require('express');
var app = express();
app.get("/myJsRoutines", loadRoutines);
app.listen(80);
Option I: XMLHttpRequest
This is a browser API that allows you to open a connection to a server and talk with the server to collect stuff using HTTP. Here's how you do this
<script>
var request = new XMLHttpRequest(); // create an xmlhttp object
request.open("GET", "/myJsRoutines"); // means GET stuff in there
request.link = link;
// wait for the response
request.addEventListener("readystatechange", function() {
// checks if we are ready to read response
if(this.readyState === 4 && this.status === 200) {
// do something with response
}
})
//send request
request.send();
</script>
Lookup XMLHttpRequest API or the new fetch API
Option II: Pug
Pug, formerly named jade is a templating engine for nodejs. How does it work? You use it to programmatically create the html on the server before sending it.
Lookup the site -> https://pugjs.org/
This is my Signal R Client.
I get this error when i run my client.(0x800a139e - JavaScript runtime error: SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. .)
The exception comes from line $.connection.hub.start
There is a ServerHub class in a folder HUBS in my Server application which runs fine.
Can anyone help me out..
Thanks
<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="http://localhost:39670/MySignalRServer/signalr/hubs"></script>
var ChatHubProxy = $.hubConnection("http://localhost:39670/MySignalRServer/signalr/hubs");
var chat = ChatHubProxy.createHubProxy('ServerHub');
chat.on("addNewMessageToPage",function (name, message) {
// Add the message to the page.
$('#discussion').append('<li><strong>' + htmlEncode(name)
+ '</strong>: ' + htmlEncode(message) + '</li>');
});
$.connection.hub.start({jsonp:true}).done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
alert("hiii");
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
Try change your code to :
<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="http://localhost:39670/MySignalRServer/signalr/hubs"></script>
var chat = $.connection.ServerHub; //here
chat.on("addNewMessageToPage", function(name, message) {
// Add the message to the page.
$('#discussion').append('<li><strong>' + htmlEncode(name)
+ '</strong>: ' + htmlEncode(message) + '</li>');
});
$.connection.hub.start().done(function() { //here
$('#sendmessage').click(function() {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
alert("hiii");
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
And make sure that this address is good - <script src="http://localhost:39670/MySignalRServer/signalr/hubs"></script>
I always use this - <script src="/signalr/hubs"></script>
And add HubName Attribute
[HubName("ServerHub")]
public class ServerHub : Hub
{
public string Send(string name, string message)
{
Clients.All.broadcastMessage(name, message);
return null;
}
}
or change this code :
var chat = $.connection.ServerHub;
to
var chat = $.connection.serverHub;
Demo project : https://github.com/czerwonkabartosz/SignalRDemo
I am trying to get data (a user's score), from an extremely simple flash game I made, to be displayed on a simple leader board which is displayed through AngularJS. You can get a copy of all of the code here (you might need to run npm install to get it to work). I am using NodeJS/Express/Socket.io to transfer the data from the game.
Here is the code from app.js (server side):
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
app.configure(function() {
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
});
io.configure(function() {
io.set('transports', ['websocket','xhr-polling']);
io.set('flash policy port', 10843);
});
var contestants = [];
io.sockets.on('connection', function(socket) {
socket.on('data', function (data) {
socket.broadcast.emit(data);
});
socket.on('listContestants', function(data) {
socket.emit('onContestantsListed', contestants);
});
socket.on('createContestant', function(data) {
contestants.push(data);
socket.broadcast.emit('onContestantCreated', data);
});
socket.on('updateContestant', function(data){
contestants.forEach(function(person){
if (person.id === data.id) {
person.display_name = data.display_name;
person.score = data.score;
}
});
socket.broadcast.emit('onContestantUpdated', data);
});
socket.on('deleteContestant', function(data){
contestants = contestants.filter(function(person) {
return person.id !== data.id;
});
socket.broadcast.emit('onContestantDeleted', data);
});
});
server.listen(8000);
The key lines from above are:
socket.on('data', function (data) {
socket.broadcast.emit(data);
});
That is where I am trying to send the data from the server side to the client side. On the client side - from within my main controller, I have this.
leader-board.js (main client side javascript file):
socket.on('data', function(data) {
$scope.score.push(data);
})
// Outgoing
$scope.createContestant = function() {
$scope.$digest;
console.log($scope.score[0]);
var contestant = {
id: new Date().getTime(),
display_name: "Bob",
score: Number($scope.score[0])
};
$scope.contestants.push(contestant);
socket.emit('createContestant', contestant);
_resetFormValidation();
};
As you can see - I am trying to get the emitted data, and push it to an array where I will keep the scores. The createContestant function gets called when the user clicks a submit button from within the main index.html file.
index.html
<body>
...
<button ng-click="createContestant()" class="btn btn-success"
ng-disabled="
ldrbd.contestantName.$error.required ||
ldrbd.contestantScore.$error.required
"
>
Submit Score
</button>
...
</body>
The line console.log($scope.score[0]);, from within the createContestant function, is always undefined. I am not sure if I am emitting the data correctly from the server side with socket.io - and I am not sure if I am receiving it correctly either. I use $scope.$digest to refresh the scope because the socket.io stuff is outside of AngularJS (or so I have read). Any help would be greatly appreciated. Again - I am trying to store data emitted from a flash game into an array, however - before the data is stored, it needs to be fetched correctly - and my fetch always turns up undefined, when it should be retrieving a number which is being emitted from the game (I know that I am emitting the number from the game because I have tested it with log messages). Thanks!
UPDATE
Changed server side code to this:
socket.on('message', function (data) {
console.log(data)
score = data;
socket.emit('score', score);
})
...and client side to this:
socket.on('score', function(data) {
console.log(data);
$scope.score = data;
});
Still no luck - but I added the console.log message to the server side to confirm that the data was getting sent and received (at least by node) and it is - the output of that message is a number which is the score. The thing I am realizing is...the score is supposed to be input on the client side when the button is clicked. But the data gets emitted from the server side when the game is over...so when the button is clicked...is the data available to the client side in that moment? Is this the discrepancy?
Here is the working socket code (took me a while but I got it)!
Server side (Node/Express):
socket.on('message', function (data) {
console.log(data);
score = data;
console.log("Transfered:" + " " + score);
//
})
socket.on('score', function() {
socket.emit('sendscore', score);
})
Client side (AngularJS)
socket.on('sendscore', function(data) {
console.log(data);
$scope.score = data;
});
// Outgoing
$scope.createContestant = function() {
socket.emit('score')
//$scope.$digest;
//console.log($scope.score[0]);
var contestant = {
id: new Date().getTime(),
display_name: "Bob",
score: $scope.score
};
$scope.contestants.push(contestant);
socket.emit('createContestant', contestant);
_resetFormValidation();
};
The link in the question still works for the code if you want to try it yourself!
I'm using namespaces to differentiate between version of my socket.io chat app, and I'm having trouble with a "cannot GET error displayed in browser."
I plan on continually updating a chat app I made in a basic socket.io tutorial, and I want to be able to launch any version of it at any time. I'm going to do this by the use of namespaces. When I launch my app in browser at the location myserverlocation/v0.0.1 to access version 0.0.1 of my app, I get an error that states cannot GET '/v0.0.1'.
This is my server code:
var app = require('express')(),
server = require('http').Server(app),
io = require('socket.io').listen(server),
chat = io.of('/v0.0.1');
server.listen(80);
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
// usernames which are currently connected to the chat
var usernames = {};
chat.on('connection', function (socket) {
// when the client emits 'sendchat', this listens and executes
socket.on('sendchat', function (data) {
// we tell the client to execute 'updatechat' with 2 parameters
io.sockets.emit('updatechat', socket.username, data);
});
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username) {
// we store the username in the socket session for this client
socket.username = username;
// add the client's username to the global list
usernames[username] = username;
// echo to client they've connected
socket.emit('updatechat', 'SERVER', 'you have connected');
// echo globally (all clients) that a person has connected
socket.broadcast.emit('updatechat', 'SERVER', username + ' has connected');
// update the list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
});
// when the user disconnects.. perform this
socket.on('disconnect', function() {
// remove the username from global usernames list
delete usernames[socket.username];
// update list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
// echo globally that this client has left
socket.broadcast.emit('updatechat', 'SERVER', socket.username + ' has disconnected');
});
});
And this is my client code:
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
var socket = io.connect('myserverlocation');
var chat = socket.of('/v0.0.1');
// on connection to server, ask for user's name with an anonymous callback
chat.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
chat.emit('adduser', prompt("What's your name?"));
});
// listener, whenever the server emits 'updatechat', this updates the chat body
chat.on('updatechat', function(username, data) {
$('#conversation').append('<b>' + username + ':</b> ' + data + '<br>');
});
// listener, whenever the server emits 'updateusers', this updates the username list
chat.on('updateusers', function(data) {
$('#users').empty();
$.each(data, function(key, value) {
$('#users').append('<div>' + key + '</div>');
});
});
// on load of page
$(function(){
// when the client clicks SEND
$('#datasend').click( function() {
var message = $('#data').val();
$('#data').val('');
// tell server to execute 'sendchat' and send along one parameter
chat.emit('sendchat', message);
});
// when the client hits ENTER on their keyboard
$('#data').keypress(function(e) {
if(e.which == 13) {
$(this).blur();
$('#datasend').focus().click();
}
});
});
</script>
<div style="float:left;width:100px;border-right:1px solid black;height:300px;padding:10px;overflow:scroll-y;">
<b>USERS</b>
<div id="users"></div>
</div>
<div style="float:left;width:300px;height:250px;overflow:scroll-y;padding:10px;">
<div id="conversation"></div>
<input id="data" style="width:200px;" />
<input type="button" id="datasend" value="send" />
</div>
My chat app works fine without the use of namespaces, at myserverlocation/. I cannot figure out why I keep getting this error. After some investigation I think my usage of io.of() is incorrect, but I cannot seem to fix the problem. I'm not sure if my problem lies in the server code, the client code, or both.
Edit: After more investigation, I think my problem lies in the follow segment of code (though I could be mistaken):
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
Edit2: The problem did in fact lie in the code segment above. I should have been sending my whole /Chat directory as static content instead of using res.sendfile() to send one file. I will formally answer my own question when stackoverflow lets me (I have to wait 8 hours to answer my own question).
I managed to find what my problem was. The problem lied in the following section of code:
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
I was sending one particular file upon connection to my server, when I should be sending my entire /Chat directory as static content. This way, I can chose what version of my chat app I would like to launch. I managed to do this by changing a few lines of code in my server code:
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
server.listen(80);
// Chat directory
app.use(express.static('/home/david/Chat'));