HTML button communicating with Node server + Socket.io - node.js

When a user clicks an html button (#new) I want to store their socket.id into an array (userQueue) on my node server but I'm having trouble figuring out how to do this. Do I need to set up a post request or is there a way through socket.io?
App.js (Server):
// App setup
var express = require('express'),
socket = require('socket.io'),
app = express(),
bodyParser = require("body-parser");
var server = app.listen(3000, function() {
console.log('listening to requests on port 3000');
});
var io = socket(server);
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static('public'));
// Room Logic
var userQueue = [];
io.on('connection', function(socket) {
console.log('made socket connection', socket.id);
socket.on('chat', function(data) {
io.sockets.emit('chat', data);
});
socket.on('typing', function(data) {
socket.broadcast.emit('typing', data);
});
});
Chat.js (client side):
// Make connection
var socket = io.connect('http://localhost:3000');
// Query DOM
var message = document.getElementById('message');
handle = document.getElementById('handle'),
btn = document.getElementById('send'),
btnNew = document.getElementById('new'),
output = document.getElementById('output'),
feedback = document.getElementById('feedback');
// Emit events
btn.addEventListener('click', function(){
socket.emit('chat', {
message: message.value,
handle: handle.value
});
});
message.addEventListener('keypress', function() {
socket.emit('typing', handle.value);
});
// Listen for events
socket.on('chat', function(data) {
feedback.innerHTML = ""
output.innerHTML += '<p><strong>' + data.handle + ':</strong>' + data.message + '</p>'
});
// Emit 'is typing'
socket.on('typing', function(data) {
feedback.innerHTML = '<p><em>' + data + ' is typing a message...</em></p>'
});
Index.html:
<!DOCTYPE html>
<html>
<head>
<title>WebSockets 101</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<link rel="stylesheet" type="text/css" href="/styles.css">
</head>
<body>
<div id="mario chat">
<div id="chat-window">
<div id="output"></div>
<div id="feedback"></div>
</div>
<input id="handle" type="text" placeholder="Handle">
<input id="message" type="text" placeholder="Message">
<button id="send">Send</button>
<button id="new">New</button>
</div>
<script type="text/javascript" src="/chat.js"></script>
</body>
</html>

I believe that a post request will probably work as well, but if you want to simply work with socket.io you can consider doing something similar to your chat event by adding this in your chat.js:
btnNew.addEventListener('click', function() {
socket.emit('new user', socket.id);
});
And on the server side, app.js:
socket.on('new user', function(id) {
userQueue.push(id);
});
And it should be stored in the array. Hope this helps!

Related

How to disconnect the user by emitting disconnect event in socket.io

Below is my server script. I want to show " a particular user has left the chat" by clicking leave button index.html which is emitting 'disconnect' event. But this doesn't seem to work. I guess it implies that default event can't be emitted. Plz help me do that. Any sort of help is appreciated.
socket.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection',function(socket)
{
//console.log("user connected")
socket.on('new user', function(data) {
console.log(data);})
socket.on('disconnect', function(data) {
console.log(data);
})
})
http.listen(3000, function(){
console.log('listening on *:3000');
})
index.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<style>
</style>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
//
$(function(){
$('#join').click(function(){
var name= $('input').val();
socket.emit('new user', name + ' has just joined the chat');
})
$('#leave').click(function(){
var name= $('input').val();
socket.emit('disconnect', name + ' has left the chat');
})
})
</script>
Choose your username <input type="text">
<button id="join" type="submit">
Enter
</button>
<button id="leave" type="submit">
Leave
</button>
</body>
try this
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
socket.on('new user', function(data) {
console.log(data)
})
socket.on('disconnect', function(data) {
console.log(data)
})
http.listen(3000, function(){
console.log('listening on *:3000');
})
}

After server starts running ,why do sockets keep on getting connected infinitely in nodejs?

I am new to nodejs,how come sockets get connected automatically till I stop the server.It should connect one socket at a time?
After I open html page in browser sockets keep on getting connected on their own!
It is expected that only one socket should be connected after server starts running.
How can I connect one socket at a time?
server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
users = [];
connections =[];
server.listen(process.env.port || 3000);
console.log('Server running');
app.get('/',function(req,res){
res.sendFile(__dirname + '/index.html');
});
io.sockets.on('connection',function(socket){
connections.push(socket);
console.log('Connected: %s sockets connected',connections.length);
socket.on('disconnect',function(data){
connections.splice(connections.indexOf(socket), 1);
console.log('Disconnected %s sockets connected',connections.length);
});
socket.on('send message',function(data){
io.sockets.emit('new message',{msg : data});
});
});
index.html
<!doctype html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap /3.3.6/css/bootstrap.min.css">
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="/socket.io/socket.io.js /"></script>
<style>
body{
margin-top:30px;}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="well">
<h3> Online users </h3>
<ul class="list-group" id="users"> </ul>
</div>
</div>
<div class="col-md-8">
<div class="chat" id="chat">
<form id="messageForm">
<div class="form-group">
<label>Enter Message</label>
<textarea class="form-control" id="message"></textarea>
</br>
<input type="submit" class="btn btn-primary" value="Send message"/>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
$(function(){
var socket = io.connect();
var $messageForm = $('#messageForm');
var $message = $('#message');
var $chat = $('#chat');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send message', $message.val());
$message.val('');
});
socket.on('new message',function(data){
$chat.append('<div class="well">'+data.msg+'</div>');
});
});
</script>
</body>
</html>
Here is a bit more complete solution with some notes for you.
Socket.io has long had some snafus with multiple connections. This can and will happen for things such as intermittent connectivity between client and server to past bugs.
You may want to also checkout ws on npmjs.com see > https://www.npmjs.com/package/ws
For some reference as to how templating works in NodeJS/Express see > https://expressjs.com/en/advanced/developing-template-engines.html
Hopefully this will put you in the right direction...
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);
const cons = require('consolidate'); // enables using any template engine.
server.maxConnections = 5; // you can limit connections to server if you wish.
const connections = [];
// Handle your template & engine.
app.engine('html', cons.swig); // where "swig" is the template lang u want to use.
app.set('views', 'your/path/to/views'); // where your views folder lives.
app.set('view engine', 'html'); // the extension of the templates without "."
app.get('/', function (req, res) {
res.render('index', { /* your locals here */ });
});
io.sockets.on('connection', function (socket) {
connections.push(socket);
console.log('Connected: %s sockets connected', connections.length);
socket.on('disconnect', function (data) {
connections.splice(connections.indexOf(socket), 1);
console.log('Disconnected %s sockets connected', connections.length);
});
socket.on('send message', function (data) { // wouldn't use event names with spaces
io.sockets.emit('new message', { // you could do something like 'message:new' & 'message:received' for the above.
msg: data
});
});
});
server.listen(process.env.port || 3000, () => {
const address = server.address();
const host = address.address;
const port = address.port;
console.log(`Server listening at ${host}:${port}.`);
});
// NOTE: Below handles ctrl-c for Win //
// This will allow for graceful shutdown of connections.
if (process.platform === "win32") { // this is required for handling on windows.
var rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("SIGINT", function () {
process.emit("SIGINT");
});
}
process.on("SIGINT", function () {
connections.forEach((socket) => {
// destroy your sockets here!
});
process.exit();
});

Socket.io getting disconnected unexpectedly

<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button onclick="message()">Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var message = function(){
var msg = document.getElementById("m").value;
if(msg !== ""){
alert(msg);
socket.emit('chat message',msg);
}
document.getElementById("m").value="";
}
socket.on('display',function(value){
console.log(value);
document.getElementById("messages").innerHTML += "<li>"+value+"</li>";
})
</script>
This is my index.html page to design a group chat using socket.io
var express = require('express');
var app = express();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
app.get('/', function(request, response) {
response.sendFile(__dirname + '/index.html');
});
io.on('connection',function(socket){
console.log('a user connected');
socket.on('chat message',function(msg){
console.log('message: '+msg);
io.emit('display',msg);
});
socket.on('disconnect',function(){
console.log('user disconnected')
})
});
http.listen(3000, function() {
console.log("listening on 3000");
});
This is my index.js file. The user is getting disconnected each time a message is sent. Any suggestions why this happened
Thanks in advance
Add message(event) to your form:
<form action="">
<input id="m" autocomplete="off" /><button onclick="message(event)">Send</button>
</form>
and change your message function to:
var message = function(event){
event.preventDefault();
var msg = document.getElementById("m").value;
if(msg !== ""){
alert(msg);
socket.emit('chat message',msg);
}
document.getElementById("m").value="";
}
The default html method when you submit a form is GET. When express receives GET it resends index.html to the browser and the page refreshes. We can change it with event.preventDefault(). It should work now.
You shouldn't do:
io.emit
You should do:
socket.emit

Basic chat application with socket/node/express - Nothing gets printed out

I am just trying to do a very basic chat application with socket.io and node. I am unable to see anything get printed out to my screen, and cannot find any errors. Appreciate the help!
Thanks.
app.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
server.listen(3000);
console.log('Server running...');
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.sockets.on('connection', function(socket){
socket.on('send-message', function(data){
io.sockets.emit('new message', data);
});
});
index.html
<html>
<title>Chat Test</title>
<style> #chat{
height: 500px;
}
</style>
<head>
<body>
<div id = "chat"></div>
<form id = "send-message">
<input size = "35" id = "message"></input>
<input type = "submit"></input>
</form>
<script src ="https://code.jquery.com/jquery-latest.min.js"></script>
<script src ="/socket.io/socket.io.js"></script>
<script>
JQuery(function($){
var socket = io.connect();
var $messageForm = $('#send-message');
var $messageBox = $('#message');
var $chat = $('#chat');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send-message', $messageBox.val());
$messageBox.val('');
});
socket.on('new message', function(data){
$chat.append(data + "<br/>");
});
});
</script>
</body>
</head>
</html>
When using jQuery, you must spell it jQuery, not JQuery or you could just use the built-in alias $.
This should have shown an error in the debug console of the browser which is something you should learn to look for to see your own errors.
jQuery(function($){
var socket = io.connect();
var $messageForm = $('#send-message');
var $messageBox = $('#message');
var $chat = $('#chat');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send-message', $messageBox.val());
$messageBox.val('');
});
socket.on('new message', function(data){
$chat.append(data + "<br/>");
});
});
After fixing this and then running your code and accessing http://localhost:3000, your app works just fine for me. Anything submitted in the form is broadcast to all connected clients.

Rethinkdb node change feed to HTML

I am trying to display any change feed from my rethinkdb database to the HTML (front-end) but I am not able to display any change feed.
Can you please help me how to solve this issue?
The file is app.js
var express = require('express'),
app = express(),
server = require('http').createServer(app),
users = {},
db='testing',
table = 'todos';
io = require('socket.io').listen(server);
var bodyParser = require('body-parser');
server.listen(5000);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
var config = require(__dirname + '/config.js');
var r = require('rethinkdbdash')(config.rethinkdb);
io.sockets.on('connection', function(socket){
r.db(db).table(table).pluck('title').changes().run().
then(function(feed){
feed.each(function(err, item){
console.log(JSON.stringify(item, null, 2));
io.emit('new message', item);
});
});
});
the config.js file
module.exports = {
rethinkdb: {
host: '192.168.2.3',
port: 28015,
authKey: '',
db: 'testing'
},
express: {
port: 5000
}
};
the index.html file
<html>
<head>
<title>Chat with socket.io and node.js</title>
<style>
#chat{
height:500px;
}
</style>
</head>
<body>
<div id="chat"></div>
<form id="send-message">
<input size="35" id="message"></input>
<input type="submit"></input>
</form>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
jQuery(function($){
var socket = io.connect();
var $messageForm = $('#send-message');
var $messageBox = $('#message');
var $chat = $('#chat');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send message', $messageBox.val());
$messageBox.val('');
});
socket.on('new message', function(data){
$chat.append(data + "<br/>");
});
</script>
</body>
</html>
you have some syntax error on index.html which prevents client side running, then the main issue is you pluck on wrong field.
Here is the code that works:
app.js
var express = require('express'),
app = express(),
server = require('http').createServer(app),
users = {},
db='testing',
table = 'todos';
io = require('socket.io').listen(server);
var bodyParser = require('body-parser');
server.listen(5000);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
var config = require(__dirname + '/config.js');
var r = require('rethinkdbdash')(config.rethinkdb);
io.sockets.on('connection', function(socket){
r.db(db).table(table)
.pluck('title')
.changes()
.run()
.then(function(feed){
feed.each(function(err, item){
console.log(JSON.stringify(item, null, 2));
io.emit('new message', item.new_val.title);
})
})
})
index.html
<html>
<head>
<title>Chat with socket.io and node.js</title>
<style>
#chat{
height:500px;
}
</style>
</head>
<body>
<div id="chat"></div>
<form id="send-message">
<input size="35" id="message"></input>
<input type="submit"></input>
</form>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
jQuery(function($){
var socket = io.connect();
var $messageForm = $('#send-message');
var $messageBox = $('#message');
var $chat = $('#chat');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send message', $messageBox.val());
$messageBox.val('');
});
socket.on('new message', function(data){
$chat.append(data + "<br/>");
});
})
</script>
</body>
</html>
Notice that, on a change feed, you get back documents like this:
{
"new_val": {
"id": "862e6410-f686-4a70-8a52-d4387181d4f2",
"title": "12"
},
"old_val": null
}
If you return the whole document, then the string concat on client $chat.append(data + "<br/>") may get an error or a string of 'object Object' because data is a object, not a string.
If you returns only title like this:
io.emit('new message', item.new_val.title);
Then the string concat will run ok.
Also, your code is very messy. I suggest you get some basic foundation of JavaScript in generally.

Resources