I am trying to create a chat application using node js and mongodb. I am looking on a tutorial for this. I couldn't solve a error that states socket is not defined while running my file server.js. The code in server Js is
var mongo = require('mongodb').MongoClient,
client = require('socket.io').listen(8080).sockets;
console.log(mongo);
mongo.connect('mongodb://#127.0.0.1/chat',function(err,db) {
if(err) throw err;
client.on('connection',function() {
//Wait for Input
socket.on('input',function(data) {
console.log(data);
});
});
});
The error is created when i wanted to listen socket on input.When i try to define socket as
socket =io.connect('http://127.0.0.1:8080'); It again gives error stating io not defined. Isn't io global on nodejs?
Please enlighten me on this.
Try as below if you are using express.
var express = require('express'),
, app = express()
, server = require('http').Server(app)
, mongo = require('mongodb').MongoClient,
, io = require('socket.io')(server);
server.listen(3000, function() {
console.log("Server Running on port 3000");
});
mongo.connect('mongodb://#127.0.0.1/chat',function(err,db) {
io.sockets.once('connection', function(socket) {
io.sockets.emit('new-data', {
channel: 'stdout',
value: "My Data"
});
});
});
In you view.html
<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.0.6.js"></script>
var socket = io.connect('http://localhost');
var streamer = $('#streamer');
socket.on('new-data', function(data) {
streamer.val(data.value);
});
</head>
<body>
<div id="streamer"> </div>
</body>
</html>
Related
I am using Angular 2 and Nodejs to Connect to an SQL Server. If I simply put following code in a js file and run it through the console using node test.js the code deletes the record properly.
Here is the code:
var webconfig = {
user: 'sa',
password: 'test',
server: 'localhost',
database: 'Test',
options: {
encrypt: false // Use this if you're on Windows Azure
}
}
var express = require('express');
var sql = require('mssql');
var http = require('http');
var app = express();
var port = process.env.PORT || 4200;
var connection = new sql.Connection(webconfig, function(err) {
var request = new sql.Request(connection);
request.query('delete from Employee where Id = 2382', function(err, recordset) {
if(err) // ... error checks
console.log('Database connection error');
console.dir("User Data: "+recordset);
});
});
app.listen(port);
console.log(port+' is the magic port');
After that I moved the same file to the src folder in my Angular 2 project (where the index.html file also exists). I put the same code into a function in test.js file like that:
function testConnection()
{
var webconfig = {
user: 'sa',
password: 'test',
server: 'localhost',
database: 'Test',
options: {
encrypt: false // Use this if you're on Windows Azure
}
}
var express = require('express');
var sql = require('mssql');
var http = require('http');
var app = express();
var port = process.env.PORT || 4200;
var connection = new sql.Connection(webconfig, function(err) {
var request = new sql.Request(connection);
request.query('delete from Employee where Id = 2382', function(err, recordset) {
if(err) // ... error checks
console.log('Database connection error');
console.dir("User Data: "+recordset);
});
});
app.listen(port);
console.log(port+' is the magic port');
}
Now I want to call testConnection() from the index page. I have put the <script src="C:\Users\amandeep.singh\Desktop\Angular\my-app\src\test.js"> to script path and call the function using this:
<script>
testConnection();
</script>
The index page executes properly but doesn't show any error nor executes the command. I'm unable to understand why the same code works in the console on Nodejs but not in my index.html.
Help will be appreciated.
You can't run Node applications in the browser. Nodejs is an application that runs Javascript in Google's V8 Javascript VM on your operating system and is meant to be a backend system (at least in the web development stack).
So you basically have to run your Node program on a webserver and make your API requests from the Angular application.
There are several tutorials out there on the internet that help you with this.
Here is the official Angular documentation angular.io
General overview of the code:
I'm trying to merge Express and Socket.IO session management using Redis. Seems to work thus far, but I'm having trouble trapping errors using domains as seen in the test below.
Server code:
"use strict";
var domain = require("domain");
var redis = require("redis");
var express = require("express");
var app = express();
var server = require("http").createServer(app);
var socketio = require("socket.io");
var redisSio = require("socket.io-redis");
// Configure Express:
app.use(require("compression")());
app.use(require("body-parser").json());
var expressSession = require("express-session");
// Configure Socket.IO:
app.io = socketio(server, {
transports: ["websocket", "polling"],
// Same name as Express cookie:
cookie: "test.sid"
});
// Manage Socket.IO sessions using Redis:
app.io.adapter(redisSio({socket: "/tmp/redis.sock"}));
// Manage Express sessions using Redis:
app.use(expressSession({
// Same name as Socket.IO cookie:
name: "test.sid",
resave: false,
saveUninitialized: false,
secret: "secret",
store: redis.createClient("/tmp/redis.sock", {
return_buffers: true
})
}));
var d = domain.create();
d.on("error", function(err) { console.log("Error"); });
d.run(function() {
// Configure listener for Socket.IO connections:
app.io.on("connection", d.bind(function(socket) {
// Configure listener for specific event:
socket.on("channel", d.bind(function(data, callback) {
// "data" is general data incoming from client.
// "callback" is a client function meant for acknowledgments.
// Generate an error:
null.test();
}));
}));
});
// Start the server:
server.listen(8080);
Client code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test</title>
<script language="javascript" type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var sock = io.connect();
if(sock) {
sock.emit("channel", null, function(data) {
$("#tester").text(JSON.stringify(data));
});
}
if(sock) {
sock.disconnect();
sock = null;
}
</script>
</head>
<body>
<p id="tester"></p>
</body>
</html>
When receiving the event from the client (triggering the error), the following is printed to the console:
Missing error handler on `socket`.
TypeError: Cannot call method 'test' of null
at Socket.<anonymous> (/home/debian/test.js:46:12)
at Socket.b (domain.js:183:18)
at Socket.emit (events.js:98:17)
at Socket.onevent (/home/debian/node_modules/socket.io/lib/socket.js:330:8)
at Socket.onpacket (/home/debian/node_modules/socket.io/lib/socket.js:290:12)
at Client.ondecoded (/home/debian/node_modules/socket.io/lib/client.js:193:14)
at Decoder.Emitter.emit (/home/debian/node_modules/socket.io/node_modules/socket.io-parser/node_modules/component-emitter/index.js:134:20)
at Decoder.add (/home/debian/node_modules/socket.io/node_modules/socket.io-parser/index.js:247:12)
at Client.ondata (/home/debian/node_modules/socket.io/lib/client.js:175:18)
at Socket.emit (events.js:95:17)
Why isn't the domain catching the error? And why is it complaining about a missing error handler on socket?
Relevant package versions:
Node.js (v0.10.38) and also io.js (v2.5.0)
Express (4.13.3)
Socket.IO (1.3.6)
Installed websocket and socket.io on the server. When I load the browser page, I get this error in the console: Uncaught TypeError: undefined is not a function
(socket.io-1.2.1.js:1)
Here is the server side code:
// Require HTTP module (to start server) and Socket.IO
var http = require('http'), io = require('socket.io');
// Start the server at port 9602
var server = http.createServer(function(req, res){
// Send HTML headers and message
res.writeHead(200,{ 'Content-Type': 'text/html' });
res.end('<h1>Hello Socket Lover!</h1>');
});
server.listen(9602);
// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);
// Add a connect listener
socket.on('connection', function(client){
// Success! Now listen to messages to be received
client.on('message',function(event){
console.log('Received message from client!',event);
});
client.on('disconnect',function(){
clearInterval(interval);
console.log('Server has disconnected');
});
});
And the client side code:
<script src="https://cdn.socket.io/socket.io-1.2.1.js"></script>
<script>
// Create SocketIO instance, connect
var socket = new io.Socket('localhost',{
port: 9602
});
socket.connect();
// Add a connect listener
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
// Add a connect listener
socket.on('message',function(data) {
console.log('Received a message from the server!',data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
console.log('The client has disconnected!');
});
// Sends a message to the server via sockets
function sendMessageToServer(message) {
socket.send(message);
}
</script>
Any help is appreciated.
k4elo
var socket = io("http://127.0.0.1:9000");
// Add a connect listener
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
The above method works with the following cdn
You are creating server on HTTP not HTTPS
<script src='/socket.io/socket.io.js'></script>
instead of script src="https://cdn.socket.io/socket.io-1.2.1.js">
I am learning Node.Js, I would like to understand how to interact between front-end / backend.
I would do backend --> Front End interaction by sendig data using app.get(), but now, I'd like to understand how can I get variable from Front End to Backend.
Front-ENd. (I want to pass varGetFromFrontend to backend)
<html>
<script>
var varGetFromFrontend = 2; // This is variable I want to pass to backend
</script>
<head>
<title>Home Page</title>
</head>
<body>
<h1> This is a test</h1>
</body>
</html>
On Node.Js (backend)
var express = require('express');
var app = new express();
app.use(express.json());
app.use(express.static(__dirname + '/public'));
var entries = [
{"id":1, "title":"Hello World!"},
{"id":2, "title":"Hello World!"}
{"id":3, "title":"Hello World!"}
{"id":4, "title":"Hello World!"}
];
if(entries.id == varGetFromFrontend){
console.log("This is to print a variable by choosing it from Front End")
console.log(varGetFromFrontend)
}
var port = Number(process.env.PORT || 5000);
app.listen(port);
I would like to know how can I print "varGetFromFrontend" on server side
Make an HTTP request to the server. Include the variable in the request.
There are lots of ways to do this:
Put it in a hidden input in a form, then submit the form.
or
Set location.href to a new value and include the variable in it (e.g. in a query string)
or
Use the XMLHttpRequest object to make an HTTP request
or
Create a script element and include the variable in the URL for the src attribute
(This is a non-exhaustive list)
You can interact with the nodejs server from the browser with socket.io
First, install socket.io:
npm install socket.io
and write these code to their respective filenames.
app.js:
var express = require("express");
var http = require("http");
var socketIO = require("socket.io");
var app = express();
app.get("/", function(req, res){
res.sendfile("./index.html");
});
var server = http.createServer(app);
var io = socketIO.listen(server, {log: false});
io.sockets.on("connection", function(socket){
socket.on("sendVar", function(value){
console.log("The value of the variable is " + value);
});
});
server.listen(5000);
index.html:
<html>
<head>
<title>Index Page</title>
</head>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var variableFromFrontEnd = 2;
var socket = io.connect("/");
socket.on("connect", function(){
console.log("connected!")
socket.emit("sendVar", variableFromFrontEnd);
});
</script>
</html>
and run it.
Check out the MEAN framework I built: http://mean.wolframcreative.com/
This uses Node as the back-end server utilizing Express as the API router. The front-end uses angular and is purely an api consumption tool.
Short answer is this:
in angular:
$http
.get('/api/users/bobsaget')
.success(function (response) {
console.log(response);
});
in node(with express):
app.get('/api/users/:username', function (req, res) {
var variable = req.params.username;
//do logic here with the database(mongo) to get user info:
db.users.findOne({username: username}, function (error, response) {
if (!error) {
res.send(200, response);
} else {
res.send(500, {success: false, message: error.message});
}
});
)};
Long answer is to play around with my framework and get your hands dirty.
I'm currently working on a restful framework for node call snooze. I'm writing an api along side it and it's going very well. The framework is written to be modular and easy to use. Everything is built around modules, routes, controllers, services, and validators.
https://github.com/iamchairs/snooze
snooze.module('myServer', ['snooze-stdlib']) // inject the snooze-stdlib module
.route('get', '/users/:username', { // define the route
controller: 'UserCtrl', // what controller should handle this route
action: 'getUserByUsername', // what action to perform on this route
validator: 'GetUsername' // before processing this action what validation should occur
})
.controller('UserCtrl', function(User) { // inject the User service
return {
getUserByUsername: function(res, options) {
User.getUserByUsername(options.query.username).then(function(username) {
res.send(200, username);
}).fail(function(err) {
res.send(500, err);
});
}
};
})
.service('User', function($q) { // inject the $q service
return {
getUserByUsername: function() {
var deferred = $q.defer();
deferred.resolve('iamchairs');
return deferred.promise;
}
};
})
.validator('GetUsername', function($validator) { // inject the validator service
return function(deferred, req) {
if($validator.isLength(req.query.username, 2, 32)) {
deferred.resolve(); // resolve (valid request)
} else {
deferred.reject([400, 'Username must be between 2 and 32 characters']); // reject (invalid request)
}
}
});
I'm trying pubsub with redis and socketio in nodejs.
My server-side code is:
var io = require('socket.io').listen(server);
var pub = redis.createClient();
io.sockets.on("connection", function(socket) {
console.log('connecteed');
var sub = redis.createClient();
sub.subscribe("messages");
sub.on("message", function(channel, message) {
console.log('message',message);
socket.emit(channel,message);
});
socket.on("disconnect", function() {
sub.unsubscribe("messages");
sub.quit();
});
});
pub.publish("messages", JSON.stringify({type: "foo", content: "bar"}));
My html page index.html contains the following script:
var host = window.location.host.split(':')[0];
var socket = io.connect('http://' + host);
socket.on('messages',function(msg){
console.log(msg);
})
but in index.html console.log is never executed.
It is elementary, but i don't find the error in my code. Where is it?
That probably because you don't have any clients connected when you publish the message (hint io.socket.on connect function is executed after pub.publish). Try to replace
pub.publish("messages", JSON.stringify({type: "foo", content: "bar"}));
with
setIntervall(function(){
pub.publish("messages", JSON.stringify({type: "foo", content: "bar"}));
},1000);
This will send the message each second and will give you plenty of time to verify your setup.