Node JS Socket IO Chat issue - javascript

I am developing a one to one chat application using node js and socket .io
but when i try running my chat.html it gives an error "Reference Error io is not defined".
I googled this issue and i found a solution it says use cdn, i tried that too . but this time error was different it is "cannot find method connect"
socket.io.js is there at node_modules\socket.io\lib
when i tried to access it through browser its says " cannot get socket.io.js"
here i am pasting my code . please help me on this
Server.js
var app = require('express').createServer();
var io = require('socket.io').listen(app);
var fs = require('fs');
app.listen(8080);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/chat.html');
});
var usernames = {};
function check_key(v) {
var val = '';
for (var key in usernames) {
if (usernames[key] == v)
val = key;
}
return val;
}
io.sockets.on('connection', function (socket) {
socket.on('sendchat', function (data) {
io.sockets.emit('updatechat', socket.username, data);
});
socket.on('adduser', function (username) {
socket.username = username;
usernames[username] = socket.id;
socket.emit('updatechat', 'SERVER', 'you have connected');
socket.emit('store_username', username);
socket.broadcast.emit('updatechat', 'SERVER', username + ' has connected: ' + socket.id);
io.sockets.emit('updateusers', usernames);
});
socket.on('disconnect', function () {
delete usernames[socket.username];
io.sockets.emit('updateusers', usernames);
socket.broadcast.emit('updatechat', 'SERVER', socket.username + ' has disconnected');
});
socket.on('check_user', function (asker, id) {
io.sockets.socket(usernames[asker]).emit('msg_user_found', check_key(id));
});
socket.on('msg_user', function (usr, username, msg) {
io.sockets.socket(usernames[usr]).emit('msg_user_handle', username, msg);
fs.writeFile("chat_data.txt", msg, function (err) {
if (err) {
console.log(err);
}
});
});
});
Chat.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<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 type="text/javascript">
var my_username = '';
try {
function send_individual_msg(id) {
socket.emit('check_user', my_username, id);
}
var socket = io.connect('http://localhost:8008');
socket.on('connect', function () {
socket.emit('adduser', prompt("What's your name?"));
});
socket.on('msg_user_handle', function (username, data) {
$('#conversation').append('<b>' + username + ':</b> ' + data + '<br>');
});
socket.on('msg_user_found', function (username) {
socket.emit('msg_user', username, my_username, prompt("Type your message:"));
});
socket.on('updatechat', function (username, data) {
$('#conversation').append('<b>' + username + ':</b> ' + data + '<br>');
});
socket.on('store_username', function (username) {
my_username = username;
});
socket.on('updateusers', function (data) {
$('#users').empty();
$.each(data, function (key, value) {
$('#users').append('<div style="cursor:pointer;" onclick="send_individual_msg(\'' + value + '\')">' + key + '</div>');
});
});
$(function () {
$('#datasend').click(function () {
var message = $('#data').val();
if (message == '' || jQuery.trim(message).length == 0)
return false;
$('#data').val('');
socket.emit('sendchat', message);
});
$('#data').keypress(function (e) {
if (e.which == 13) {
$(this).blur();
$('#datasend').click();
}
});
});
}
catch (err) {
alert(err);
}
</script>
</head>
<body>
<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: 550px; 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>
</body>
</html>

Since you are using Express, you should put your client-side socket.io.js file in the
public/javascripts
and in your HTML file the path of your file will be :
javascripts/socket.io.js

Since you are using a static file, that is socketio.js you need to use
//For including static files in expressJS
app.use(express.static(__dirname + '/'));
or
Express provides a built-in middleware express.static to serve static files, such as images, CSS, JavaScript, etc.
You simply need to pass the name of the directory where you keep your static assets, to the express.static middleware to start serving the files directly. For example, if you keep your images, CSS, and JavaScript files in a directory named public, you can do this −
app.use(express.static('public'));
Place your /socket.io/socket.io.js in side public directory

Related

Socket.io not able to handle multiple clients javascript

I am working on a node.js app where I am using socket.io to send data to multiple clients but the socket is only able to send data to one client i.e if I open my webpage in two tabs its not working in both the tabs but when I open just 1 tab of webpage it is able to transmit the data.I dont know why? Can someone help,Here's my code:
server.js
var http = require("http"),
io = require("socket.io"),
fs = require("fs"),
util = require("util");
var backlog_size = 2000;
var filename = process.argv[2];
if (!filename) return util.puts("Usage: node <server.js> <filename>");
var linesCount = 0;
// -- Node.js HTTP Server ----------------------------------------------------------
server = http.createServer(function (req, res) {
console.log(req.url)
filePath = req.url
if(filePath=="/"){
filePath='./index.html'
fs.readFile(filePath, function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading ' + filePath);
}
res.writeHead(200);
res.end(data);
});
}
else
{
if(filePath=="/client"){
filePath = './client.html';
fs.readFile(filePath, function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading ' + filePath);
}
res.writeHead(200);
res.end(data);
});
}}
});
server.listen(8000, "0.0.0.0");
var fsTimeout
var textToSend=""
// -- Setup Socket.IO ---------------------------------------------------------
var socket = io(server, {
cors: {
origin: "*",
},
});
socket.on("connection", function (client) {
fs.watchFile(filename, function (curr, prev) {
console.log("file changed");
if (prev.size > curr.size) return { clear: true };
if(!fsTimeout){
if(prev.ctime.getTime() != curr.ctime.getTime())
{
console.log("file changed")
var stream = fs.createReadStream(filename, {
start: prev.size,
end: curr.size,
});
stream.on("data", function (lines) {
console.log(lines.toString());
textToSend+=lines.toString();
textlen=textToSend.split("\n").length;
// count=lines.toString().split("\n").length
// linesCount += count;
// console.log(linesCount);
console.log(textlen)
if(textlen<10)
{
console.log("me")
client.emit("tail", { lines: lines.toString("utf-8").split("\n") });}
else
{
console.log("client")
client.emit("room", { lines: textToSend.toString("utf-8").split("\n") }); };
});
}
fsTimeout = setTimeout(function() { fsTimeout=null }, 5000)}
}
);
});
In the above code I have added 2 clients,1 page is index.html and other is client.html and both are opening in the browser and getting connected to the socket but the data is not transmitting to any of them.Here's are my client codes:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Websockets tail Server</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
</head>
<body>
<div id="info" class="trebuchet"></div>
<div id="tail" class="monospace selection"></div>
<script type="text/javascript">
(function() {
var lines = 0, notice = $("#info"), buffer = $('#tail');
var socket = io.connect('http://127.0.0.1:8000/');
socket.on('connect', function() {
console.log('Connected to stream');
});
socket.on('room', function(msg) {
console.log("Message:");
console.dir(msg);
buffer.append(msg.lines.join('<br/>'));
buffer.scrollTop(lines*100);
lines = lines + msg.lines.length;
});
})();
</script>
</body>
</html>
client.html
<!DOCTYPE html>
<html>
<head>
<title>Websockets tail Server</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
</head>
<body>
<div id="info" class="trebuchet"></div>
<div id="tail" class="monospace selection"></div>
<script type="text/javascript">
(function() {
var lines = 0, notice = $("#info"), buffer = $('#tail');
var socket = io.connect('http://127.0.0.1:8000/');
socket.on('connect', function() {
console.log('Connected to stream');
});
socket.on('tail', function(msg) {
console.log("Message:");
console.dir(msg);
buffer.append(msg.lines.join('<br/>'));
buffer.scrollTop(lines*100);
lines = lines + msg.lines.length;
});
})();
</script>
</body>
</html>
Both the html files above are my clients and I want them to listen to my socket server but they are not but when I remove one of the clients,it works.
Any help will be appreciated

NodeJS+Socket.io Chat app making fresh connection every time a new message is sent

I am developing a real-time chat room using socket.io. On pressing the "Send" button, the page reloads and a new connection is made. I know I am missing on the placement of the javascript code.
I followed this tutorial http://javabeginnerstutorial.com/javascript-2/create-simple-chat-application-using-node-js-express-js-socket-io/#comment-4868 but couldn't get the code to work. Tried every possible pattern.
server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var path = require('path');
app.set('port', (process.env.PORT || 3000));
app.get('/', function(req, res) {
var express = require('express');
app.use(express.static(path.join(__dirname)));
res.sendFile(path.join(__dirname, '../ATTEMPT-2', 'index.html'));
});
io.on('connect', function(socket) {
console.log('A new user is connected');
socket.on('chatMessage', function(from, msg) {
io.emit('chatMessage', from, msg);
});
socket.on('notifyUser', function(user) {
io.emit('notifyUser', user);
});
});
http.listen(app.get('port'), function() {
console.log('The application is running on port ' + app.get('port'));
});
chat.js
$(document).ready(function() {
var socket = io();
function submitFunction() {
var from = $('#user').val();
var message = $('#m').val();
if (message != '') {
socket.emit('chatMessage', from, message);
}
$('#m').val('');
return flase;
}
function notifyTyping() {
var user = $('#user').val();
socket.emit('notifyUser', user);
}
socket.on('chatMessage', function(from, msg) {
var me = $('#user').val();
var color = (from == me) ? 'green' : '#009afd';
var from = (from == me) ? 'Me' : from;
$('#messages').append('<li><strong style="color:' + color + '">' + from
+ '</strong>:' + msg + '</li>');
});
socket.on('notifyUser', function(user) {
var me = $('#user').val();
if (user != me) {
$('#notifyUser').text(user + 'is typing...');
}
setTimeout(function() {
$('#notifyUser').text('');
}, 10000);
});
// CREATE USERS
var name = makeId();
$('#user').val(name);
socket.emit('chatMessage', 'System', '<strong>' + name + '</strong> has
joined the conversation!');
});
function makeId() {
var text = "";
var possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 5; i++) {
text += possible.charAt(Math.floor(Math.random()*possible.length));
}
return text;
}
index.html -> putting out only the important part
<head>
<title>Chat App | DB</title>
<link rel="stylesheet" href="css/main.css">
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script src="chat.js"></script>
</head>
<body>
<div class="chat">
<input type="text" class="chat-name" placeholder="Enter your name">
<div class="chat-messages">
<ul id="messages"></ul>
<span id="notifyUser"></span>
</div>
<div id="sending-form">
<form id="form" action="" onsubmit="return submitFunction();">
<input type="hidden" id="user" value="" />
<input id="m" autocomplete="off" onkeyup="notifyTyping();"
placeholder="Type yor message here.." />
<input type="button" class="btn btn-primary" id="send-btn" value="Send">
</form>
</div>
</div>
</body>
The reason it is making a fresh connection every time is because every time you submit the form, your page is refreshing, so with every refresh it is calling var socket = io(); therefore establishing a new connection with the server. Consider performing an AJAX request every time you want to send the form, or override the default refresh behavior of your form.

CSS doesn't load into my HTML code using Node.js

I'm trying to add CSS to my HTML using express() function in localhost:3000 by Node.js.
Unfortunately, something is weird. I followed the steps from tutorial step by step but still my css doesn't load. My style.css is in css folder (css/style.css). Here is my code:
app.js (note that I used app and app1)
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
var fs = require('fs');
var express = require('express');
var app1 = express();
var mySocket = 0;
app1.use(express.static('/css'));
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.sockets.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);
style.css (css/style.css)
.test
{
color:red;
}
index.html
<html>
<head>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<link rel="stylesheet" type="text/css" href="/css/style.css" />
</head>
<body>
<script>
var socket = io.connect('http://localhost:3000');
socket.on('field', function (data) {
console.log(data);
$("#field").html(data);
});
</script>
<div class='test'>Data from C#: </div><div id="field"></div>
</body>
</html>
You set the root of the static module to /css here
app1.use(express.static('/css'));
but then you request /css/style.css which means express looks for the file in /css/css/style.css (note that this path is absolute and not relative to your project).
Put everything in a public folder, e.g. public/css/style.css and then
app1.use(express.static(__dirname + '/public'));
Edit: Here's a minimal working example which serves the index.html and the style.css (in public/css/style.css)
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.get('/index.html', function(req, res, next) {
res.sendFile(__dirname + '/index.html');
});
app.listen(3000);

Two people cant type simultaneously in a simple collaborative document

Here is my code
server.js
var http = require('http');
var app = require('express')();
var server = http.createServer(app).listen(process.env.PORT, process.env.IP);
var io = require('socket.io').listen(server);
var textData = "some random initial text that will be changed forever, never to be restored to its original state."
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
var users = 0;
io.on('connection', function(socket){
users++;
console.log(users + " users are here.");
//broadcast recieved data
socket.on('textChange', function(text){
textData = text;
socket.broadcast.emit('updatedText', textData);
});
socket.on("disconnect", function(){
users--;
console.log(users + " users are here.");
})
});
index.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
/* global io */
var socket = io();
$(document).ready(function() {
//send value on key up
$('#textarea').keyup(function(){
socket.emit('textChange', $('#textarea').val());
});
//recieve changed value
socket.on('updatedText', function(text){
$('#textarea').val(text);
});
});
</script>
<style type="text/css">
form, form * {
width: 100%;
height: 400px;
}
</style>
</head>
<body>
<h1>HELLO</h1>
<h2></h2>
<form action="">
<textarea id="textarea"></textarea>
</form>
</body>
</html>
It is working as inteded but when the two people type simultaniously, it alternates between them and just bugs out. How can I make it so that two people can type together.
I am thinking about using diff-patch but Im not sure if it will even solve this issue.
Please Help.
maybe you can add some user identifier(e.g. sessionid or uuid or other stuff) to recognize the users,etc:
// add user id
var user = Math.random();
$('#textarea').keyup(function(){
socket.emit('textChange', {name: user, val: $('#textarea').val()});
});
//recieve changed value
socket.on('updatedText', function(text){
if (text.user == user) {
$('#textarea').val(text.val);
}
});

My node.js server script is serving the index.html fine, but not the CSS or other static files

I am trying to write a Node.js project from a tutorial, but the server.js file does not seem to be working properly:
var http = require('http');
var fs = require('fs');
var path = require('path');
var mime = require('mime');
var cache = {};
function send404(response) {
response.writeHead(404, {'Content-Type': 'text/plain'});
response.write('Error 404: not found');
response.end();
}
function sendFile(response, filePath, fileContents) {
response.writeHead(
200,
{"content-type": mime.lookup(path.basename(filePath))}
);
response.end(fileContents);
}
function serveStatic(response, cache, absPath) {
if (cache[absPath]) {
sendFile(response, absPath, cache[absPath]);
} else {
fs.exists(absPath, function(exists) {
if (exists) {
fs.readFile(absPath, function(err, data) {
if (err) {
send404(response);
} else {
cache[absPath] = data;
sendFile(response, absPath, data);
}
});
} else {
send404(response);
}
});
}
}
var server = http.createServer(function(request, response) {
var filePath = false;
if(request.url == '/') {
filePath = 'public/index.html';
} else {
filePath = '/public/' + request.url;
}
var absPath = './' + filePath;
serveStatic(response, cache, absPath);
});
server.listen(26353, function() {
console.log("Listening...");
});
When I go to my URL the index.html content is displayed, but none of the stylesheets or attached files from the index.html are displayed, I get:
GET http://myURL.com/stylesheet/style.css 404 (NOT FOUND)
Here is my index.html:
<html>
<head>
<title>Chat</title>
<link rel='stylesheet' href='/stylesheet/style.css'></link>
</head>
<body>
<div id='content'>
<div id='room'></div>
<div id='room-list'></div>
<div id='messages'></div>
<form id='send-form'>
<input id='send-message' />
<input id='send-button' type='submit' value='Send' />
<div id='help'>
Chat commands:
<ul>
<li>.....</li>
</ul>
</div>
</form>
</div>
<script src='/socket.io/socket.io.js' type='text/javascript'></script>
<script src='http://code.jquery.com/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='/javascript/chat.js' type='text/javascript'></script>
<script src='/javascript/chat_ui.js' type='text/javascript'></script>
</body>
</html>
I'm not sure what is wrong.
My project directory has the server.js, the node-modules and the public folder, the public folder has a stylesheet directory and javascript folder where the files are.
My web host has is set up so that http://myURL.com/node/ is where port 26353 is bound to (don't know if that's the right word). So if I go to http://myURL.com/node I see the index.html file but none of the stylesheets or javascript works.
Sending file is not so trivial in node.js. There is a code from my framework
core.sendFile = function(filename, context)
{
if (fs.exists(filename, function (exists)
{
if (exists) fs.stat(filename, function (err, stats)
{
if (err) core.catch_err(err);
else if (stats && !stats.isDirectory())
{
var filestream = new fs.ReadStream(filename);
var mimme = mime.lookup(filename);
context.response.writeHead(200, {'Content-Type': mimme });
filestream.pipe(context.response);
filestream.on("error", function (err) { context.response.statusCode = "500"; context.response.end("Server error"); core.log("Server error while sending " + filename, "err"); });
context.response.on("close", function () { filestream.destroy(); });
core.logger.log("Sending file " + filename);
}
});
else core.not_found(context);
}));
}
The idea is to read and write file as a stream, and to process some errors and closing of streams. "Core" is just a library object.
remove the first / from your url, so it should be stylesheet/style.css instead of /stylesheet/style.css

Categories