I am creating a chat where there will be a div that displays the users that have connected to the server. The user's name is being taken from a prompt. I have managed to push each connected user to the array but can't figure out how to display that array. At the moment it only appends the div with the name of the individual user but I want them all to be displayed.
<body>
<div id="chatlog" class="col-sm-9">
<ul id="messages"></ul>
</div>
<div id="online" class="col-sm-3">
<div id="username"></div>
</div>
<form class="col-sm-12" action="">
<input id="type" type="text" />
<input type="submit" id="submit" />
</form>
<script>
var socket = io();
var user = prompt("What's your name?");
$('form').submit(function() {
socket.emit('chat message', $('#type').val());
$('#type').val('');
return false;
});
socket.on('chat message', function(msg) {
$('#messages').append($('<li>').text(msg));
});
socket.emit("join", user);
socket.on("join", function(user) {
$("#username").append($("<p>").text(user));
})
</script>
</body>
server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var express = require("express");
var port = 3000;
var onlineUsers = [];
console.log(onlineUsers);
app.use(express.static(__dirname + '/'));
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket) {
console.log('a user connected');
socket.on("join", function(user) {
socket.emit("join", user);
onlineUsers.push(user);
console.log(onlineUsers);
});
socket.on('chat message', function(msg) {
console.log('message: ' + msg);
io.emit('chat message', msg);
});
socket.on('disconnect', function() {
console.log('user disconnected');
});
});
http.listen(port, function() {
console.log('listening on *:' + port);
});
I am also open to suggestions how to do this another way but node.js is very new to me and think this might be the easiest way.
Send the array of users back to the clients when a user joins. This way all clients will have a updated user list every time a user joins. Below is a suggestion on how you could implement this
server:
socket.on("join", function(user) {
onlineUsers.push(user);
io.emit("user list", onlineUsers);
});
client:
socket.emit("join", user);
socket.on('user list', function(onlineUsers) {
$("#username").empty();
for(var i=0;i<onlineUsers.length;i++){
$("#username").append($("<p>").text(onlineUsers[i]));
}
});
Related
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');
})
}
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();
});
<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
I am trying to make simple chat app using socket.io. Manually it's working fine (via browser localhost:3000/) but I want to write unit tests to verify logic of the server. I don't know which tools/libraries to use for testing.
Here is my node server code:
index.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var socketCount = 0;
http.listen(3000, function(){
console.log('listening on *:3000');
});
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket) {
socketCount++;
console.log('new user connected');
// Let all sockets know how many are connected
io.emit('users connected', socketCount);
socket.on('disconnect', function(){
// Decrease the socket count on a disconnect, emit
socketCount--;
io.emit('users connected', socketCount);
});
socket.on('chat message', function(msg){
// New message added, broadcast it to all sockets
io.emit('chat message', msg);
});
});
And here is my html page:
file: index.html
<html>
...
<body>
<ul id="messages"></ul>
<div class='footer'>
<div id="usersConnected"></div>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</div>
</body>
...
<script>
$(document).ready(function(){
$('#messages').val('');
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
// New message emitted, add it to our list of current messages
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
// New socket connected, display new count on page
socket.on('users connected', function(count){
$('#usersConnected').html('Users connected: ' + count);
});
});
</script>
</html>
Thanks.
I had this problem: How to do unit test with a "socket.io-client" if you don't know how long the server take to respond?.
I've solved so using mocha and chai:
var os = require('os');
var should = require("chai").should();
var socketio_client = require('socket.io-client');
var end_point = 'http://' + os.hostname() + ':8081';
var opts = {forceNew: true};
describe("async test with socket.io", function () {
this.timeout(10000);
it('Response should be an object', function (done) {
setTimeout(function () {
var socket_client = socketio_client(end_point, opts);
socket_client.emit('event', 'ABCDEF');
socket_client.on('event response', function (data) {
data.should.be.an('object');
socket_client.disconnect();
done();
});
socket_client.on('event response error', function (data) {
console.error(data);
socket_client.disconnect();
done();
});
}, 4000);
});
});
My chat application is working properly on local server, but when I am pushing it to the openshift server, the chat functionality is not working.
I am following this example : http://socket.io/get-started/chat/
The following is my HTML code
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function () {
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function (msg) {
$('#messages').append($('<li>').text(msg));
});
</script>
</body>
Below is my server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var ipaddress = process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1";
var port = process.env.OPENSHIFT_NODEJS_PORT || 3000;
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
socket.on('chat message', function (msg) {
io.emit('chat message', msg);
});
});
http.listen(port, function () {
console.log('listening');
});
The same code is working fine on my local server. For now I am simply broadcasting the message including the sender too.
Where am I wrong?
$( document ).ready(function() {});
this code saved me. i forgot to enclose my scripting in jquery document ready. so the final code looks like this.
$( document ).ready(function() {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
});
Your chat client needs to connect to the websocket chat server on port 8000 for ws (or 8443 for wss). Make sure you are specifying that port number when you have it connect.
I know it´s a bit late, but the document isn´t ready and that caused the error.
Try this code:
$( document ).ready(function() {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
});