Problems broadcasting messages with Socket.io - javascript

I am trying to output a message of 'XYZ is typing' whenever a user begins typing but I can't seem to fix my code. I feel as if the 'socket.broadcast.emit' in the App.JS of my code is the issue but I am not sure. If possible can somebody point me in the right direction to helping me fix my chat app. Thanks in advance!
Index.HTML
<!doctype html>
<html>
<head>
<title>Chit Chat</title>
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<ul id="messages"></ul>
<div id="typing"></div>
<form action="">
<input id="username" placeholder="Username" type="text" />
<input id="message-box" autocomplete="off" type="text" placeholder="Type Message" />
<button id="button">Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="/js/scripts.js" charset="utf-8"></script>
</body>
</html>
App.JS (Server)
var express = require('express');
var app = require('express')();
var bodyParser = require('body-parser');
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}))
app.use(express.static('./public'));
app.get('/', function(req, res){
res.sendFile(__dirname + '/views/index.html');
});
var port = process.env.PORT || 3000;
http.listen(port, function(){
console.log('listening on ' + port);
});
// Socket.io
io.on('connection', function(socket) {
// when the client emits 'new message', this listens and executes
socket.on('new message', function(data) {
// we tell the client to execute 'new message'
io.sockets.emit('new message', data);
});
// when the client emits 'typing', we broadcast it to others
socket.on('typing', function(data){
socket.broadcast.emit('typing', data);
});
});
Scripts.JS
console.log('Loaded');
var socket = io();
$(function (){
chat();
emitEvents();
isTyping();
});
function chat() {
$('form').submit(function(e){
var message = {
username: $('#username').val(),
message: $('#message-box').val()
}
e.preventDefault();
socket.emit('new message', message);
$('#message-box').val('');
});
}
function isTyping() {
$('#message-box').keypress(function() {
socket.emit('typing', $('#username').val());
});
}
function emitEvents() {
socket.on('typing', function(data){
console.log(data);
$('#typing').append($('<p>').text(data + 'is typing'));
});
socket.on('new message', function(data){
$('#messages').append($('<li>').text(data.username + ': ' +
data.message));
});
}

I tried your code and it's working. I have created a live example.
I made 2 modifications in scripts.js, so the typing message will appear only once during the typing.
function emitEvents() {
socket.on('typing', function(data){
console.log(data);
$('#typing').html($('<p>').text(data + ' is typing')); // update
});
socket.on('new message', function(data){
$('#typing').html($('<p>').text('')); // update
$('#messages').append($('<li>').text(data.username + ': ' + data.message));
});
}
The code socket.broadcast.emit means sending to all clients except sender.
Check out the Socket.IO cheatsheet.

Related

Socket.io app does not work on phone client

I have a socket.io app that works perfectly on chrome, safari and opera, with notifications made using push.js.
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="https://cdn.rawgit.com/Nickersoft/push.js/master/push.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
var socket = io();
var username = prompt("What's your name?");
var notification = new Audio('https://cdn.rawgit.com/InfiniaPress/Passenger-Pigeon/master/assets/notification.mp3');
if(username){
socket.emit('connection info', username);
}
function send(message) {
$('#messages').append($('<li>').text(message));
}
socket.on('user add', function(usr){
send(usr.username + " has joined.");
});
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('user left', function(usr){
send(usr.username + " has disconnected.");
})
socket.on('chat message', function(msg, usr){
Push.create('Passenger Pigeon', {
body: usr.username + ": " + msg,
icon: "https://cdn.rawgit.com/InfiniaPress/Passenger-Pigeon/master/assets/pigeon-final.png",
timeout: 4000,
onClick: function () {
window.focus();
this.close();
},
vibrate: [200, 100, 200, 100, 200, 100, 200]
});
notification.play();
send(usr.username + ": " + msg);
});
</script>
</body>
</html>
The above is my client side.
var express = require('express'); // Get the module
var app = express(); // Create express by calling the prototype in var express
var http = require('http').Server(app);
var io = require('socket.io')(http);
// Import events module
var events = require('events');
// Create an eventEmitter object
var eventEmitter = new events.EventEmitter();
var config = require('./config.json');
app.get('/', function(req, res){
res.sendFile(__dirname + '/view/index.html');
});
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg, {username: socket.username});
});
socket.on('connection info', function(usr){
socket.username = usr;
io.emit('user add', {username: usr});
});
});
io.on('connection', function(socket){
console.log('Passenger Pigeon >> a user connected');
socket.on('disconnect', function(){
socket.broadcast.emit('user left', {
username: socket.username,
});
console.log('Passenger Pigeon >> user disconnected');
});
});
http.listen(process.env.PORT || config.port, function(){
console.log('listening on *:' + config.port);
});
^that is my server side.
When I open the app on mobile the [username] has joined prints out, but all messages do NOT appear on the client side. Other computers receive the messages. Why is this so?

Cant retrieve simple broadcast message in the HTML file using NodeJS/Socket.io

I am studying NodeJS together with Socket.io
I have a very simple chat page. But I don't know where's my error.
Here's my simple code:
index.js
var express = require('express');
var app = express();
app.use('/', express.static(__dirname + '/'));
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
//res.send('<h1>Hello World</h1>');
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
//console.log('a user is connected!');
socket.on('disconnect', function() {
//console.log('user disconnected!');
});
socket.on('chat message', function(msg) {
io.emit('chat message: ' + msg);
});
});
http.listen(3000, function() {
console.log('listening on *:3000');
});
index.html
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="on" /><button>Send</button>
</form>
<script type="text/javascript" src="jquery-1.12.4.js"></script>
<script src="/socket.io/socket.io.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) {
console.log(msg); //NO VALUE?
});
</script>
</body>
I can't get the value on this line:
socket.on('chat message', function(msg) {
console.log(msg); //NO VALUE?
});
The message can not be received on the client because, with
// Server: Receive and send message
socket.on('chat message', function(msg) {
io.emit('chat message: ' + msg);
}
you emit an event named chat message: ${msg}, but this is an event you are not listening on the client side.
When emitting an event you do this by defining the event name first, and then specifying the data as second parameter in JSON format. Changing the code above to
// Server: Receive and send message
socket.on('chat message', function(data) {
io.emit('chat message', { message : data.message });
}
will emit the event to the client with the message as the data. Same syntax applies, when sending the event from the client to the sever. So change
// Client: Send message
$('form').submit(function() {
socket.emit('chat message', $('#m').val());
to
// Client: send message
$('form').submit(function() {
socket.emit('chat message', {message : $('#m').val()});
When the server answers your event, you can then receive and access the message as follows:
// Client: Receive message
socket.on('chat message', function(data) {
console.log(data.message); // VALUE :-)
});

Why is my $.get() callback function never called, when sending data to the Express server?

Can someone tell me why my callback function:
$.get("http://localhost:8080/", msg, function(data) {
alert("Data" + data);
});
is never called?
The server gets the request and prints to the console, but my client (HTML page below) never seems to get a response.
Here is the Express server:
var express = require('express');
var app = express();
app.get('/', function(req, res) {
console.log("Message! : GET");
res.send('Hello World');
});
app.post('/', function(req, res) {
console.log("Message! : POST");
res.send('Hello World');
});
var server = app.listen(8080, function() {
var host = server.address().address;
var port = server.address().port;
console.log('Listening at http://%s:%s', host, port);
});
And here is the HTML page making request to the server:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Client</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<h1>Client</h1>
<form action="">
<fieldset>
Name:<br><br>
<input type="text" id="name" name="name">
<br><br>
Message:<br><br>
<input type="text" id="message" name="message">
<br><br>
<input type="submit" id="submit" value"Submit">
</fieldset>
</form>
<br><br>
<textarea style="max-height:400px; min-height:400px; max-width:300; min-width:300px; resize: none"></textarea>
</textarea>
<script type="text/javascript">
document.getElementById("submit").addEventListener("click", function(e) {
var msg = {
Name: document.getElementById("name").value,
Message: document.getElementById("message").value
};
$.get("http://localhost:8080/", msg, function(data) {
alert("Data" + data);
});
}, false);
</script>
</body>
</html>
Try to use the code below to see what error message you get (Posted as response for lisibility of code)
$.ajax({
url: 'http://localhost:8080/',
type: 'GET',
success: function(data){
},
error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
}
});

How to send a callback function in angular after/while http request?

I am using an angular controller to send an http post request to my express route and then data is being sent to my gmail client using nodemailer. The $http request works and I do receive emails in my gmail clients however when I try to log information to my console or create javascript alerts nothing happens. Ideally when a user sends an email through the contact form I would like two alerts. 1.) email is being sent and 2.) email has been sent! The problem is that the callback functions in angular won't allow me to do so? any ideas? Cheers!
/* server.js */
var express = require('express');
var app = express();
var http = require('http');
var httpServer = http.Server(app);
var nodemailer = require('nodemailer');
var bodyParser = require('body-parser');
app.use(bodyParser.json({}));
app.use(express.static(__dirname + '/public'));
app.use('/', express.static(__dirname + '/public'));
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
var server = app.listen(9000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'solarcode94#gmail.com',
pass: '********'
}
});
app.route('/').post(function(req, res) {
var data = req.body;
transporter.sendMail({
from: data.contactEmail,
sender: data.contactEmail,
to: 'solarcode94#gmail.com',
subject: 'Message from ' + data.contactName,
text: data.contactEmail + 'swws' + data.contactMsg
});
});
<!-- index.html -->
<!DOCTYPE html>
<html lang="en" ng-app="mailingApp">
<head>
<meta charset="UTF-8">
<title>nodejs mailing</title>
<script src="http://code.angularjs.org/1.2.13/angular.js"></script>
<script src="node-email-controller.js"></script>
</head>
<body ng-controller="mailingCtrl">
<form name="contactForm" data-ng-submit="sendMail()" novalidate>
Name: <input type="text" data-ng-model="contactName">
Email: <input type="text" data-ng-model="contactEmail">
Message: <textarea ng-model="contactMsg" columns="1" required></textarea>
<button type="submit">Send</button>
</form>
</body>
</html>
/* angular controller */
var mailingApp = angular.module('mailingApp', []);
mailingApp.controller('mailingCtrl', ['$scope', '$http', function($scope, $http){
$scope.sendMail = function(){
var data = ({
contactName : this.contactName,
contactEmail : this.contactEmail,
contactMsg : this.contactMsg
});
$http.post('/', data).
then(function(response) {
}, function(response) {
});
};
}]);
If you are familiar with nodemailer or express sometimes I end up receiving two emails per form submission and have no idea how to solve that. Thanks!
First, this needs some kind of a response returned:
app.route('/').post(function(req, res) {
var data = req.body;
transporter.sendMail({
from: data.contactEmail,
sender: data.contactEmail,
to: 'solarcode94#gmail.com',
subject: 'Message from ' + data.contactName,
text: data.contactEmail + 'swws' + data.contactMsg
});
});
Second, you could do the alerts like this:
$scope.sendMail = function(){
var data = ({
contactName: this.contactName,
contactEmail: this.contactEmail,
contactMsg: this.contactMsg
});
alert('Sending the email');
$http.post('/', data).then(function(response) {
// provided that the `transporter.sendMail` returned a good response
alert('The email was sent');
}, function(response) {
// provided that the `transporter.sendMail` returned a bad response
alert('The email did not send');
});
};

Socket.io > Simple server to client message

my problem between socket.io and HTML5
Javascript Server:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function (req, res) {
res.sendfile('index.html');
});
io.on('connection', function (socket) {
socket.emit('news', 'Hello');
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
HTML5:
<html>
<head>
<meta charset="UTF-8">
<title>My Title</title>
</head>
<body>
<input type="button" id="getButton" value="Get Rooms">
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$("#getButton").click(function () {
socket.on('news', function (data) {
alert(data);
});
});
</script>
</body>
</html>
When I click on the button (ID: getButton) I don't get an alert. The server ist working and I can access the page without any problems.
I am currently a newbie in socket.io/javascript (installed yesterday), if you have good informative pages about socket.io please post the link under this topic, thanks.
best regards
You're emitting the news message as soon as you connect, so it has already fired by the time you click your button. Try changing your code to this and you should see your alert:
var socket = io();
socket.on('news', function(data) {
alert(data);
});
You could trigger the event on a button with something like this:
Server:
io.on('connection', function(socket) {
//socket.emit('news','Hello');
});
// Return the news when it's requested
io.on('giveMeNews', function(socket) {
socket.emit('news', 'Here is your news');
});
Client:
// Listen for the news message
socket.on('news', function(data) {
alert(data);
});
// Request news from the server
$("#getButton").click(function() {
socket.emit('giveMeNews');
)};

Categories

Resources