I have a problem with nodejs and socket.io
I tried in other discussions in order to understand how to solve my problem , but I did not succeed .
I'm going to create a board with score and I created a simple counter in javascript . I want to convey to all who open the ' localhost address : port with nodejs advances counter
this is what I have made so far
tabellone.js
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http)
app.use(express.static(__dirname + '/public'));
io.emit('some event', { for: 'everyone' });
io.on('connection',function(socket){
socket.on('contatore', function(){
socket.broadcast.emit('contatore', contatore);
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
index.html
<html>
<head>
<title>tab</title>
</head>
<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 src="/socket.io/socket.io.js"></script>
<body>
<ul id="tab"></ul>
<form id="form">
<p id="contatore">0</p>
<button id="m" type="button"
onClick="javascript:contatore_su();"> + </button>
<button type="button"
onClick="javascript:contatore_giu();"> - </button>
</form>
<script>
var s=0;
function contatore_su() {
s=s+1;
document.getElementById('contatore').innerHTML = s;
}
function contatore_giu() {
s=s-1;
document.getElementById('contatore').innerHTML = s;
}
</script>
<script>
var socket=io();
$('form').click(function(){
socket.emit('conteggio', $('#m').val());
$('#m').val('');
return false;
});
socket.on('conteggio', function(msg){
$('#tab').append($('<li>').test(msg));
});
</script>
</body>
</html>
I have previously created a chat by following what is written on socket.io but I can not convey to all connected sockets the advancement counter , thanks for the help
ps. Sorry for my english :')
Which is the code to trasmit the element, in this case that is
contatore
I do not know what to put in the
io.on('connection',function(socket){ //here what? });
I do not know how the insert of the fuction works
Related
I am currently trying to change the volume of my Raspberry Pi with two html buttons (volume up and volume down), using nodeJS. The volume change is done by calling a bash script when clicking on one of the html-buttons in index.html.
When I start node manually from terminal with
node server.js
everything works fine and I can increase and decrease the volume using the two buttons.
As soon as I put the node script to autostart, only the "volume up" button is working, while the volume down does not seem to be working.
Killing the autostarted node process and starting it manually, it works just fine again.
How can the outcome be this different, depending on how node is started here?
What is my error in this?
My node script looks like this:
var express = require('express');
var path = require('path');
var open = require('open');
var fs = require('fs');
const { exec } = require('child_process');
var bodyParser = require('body-parser');
var port = 3000;
var app = express();
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, 'index.html'));
});
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/', function(request, respond) {
var inputValue = request.body.volume;
if (inputValue == "up") {
exec('sh volumeup.sh');
}
if(inputValue == "down") {
exec('sh volumedown.sh');
}
});
app.listen(port, function(err){
if(err){
console.log(err);
}else{
open('http://localhost:' + port);
}
});
with my index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<h2>Change Volume</h2>
<form action="" method="post">
<button name="volume" value="up">Volume Up</button>
<button name="volume" value="down">Volume Down</button>
</form>
</body>
</html>
To get the nodejs to run on autostart, I have set up a *.desktop-file:
[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=<Node>
Comment=
Exec=/usr/bin/node /home/pi/Desktop/server.js
StartupNotify=false
Terminal=true
Hidden=false
Thank you very much in advance, I really appreciate your help!
Figured it out by myself.
In case anyone is facing a similar issue:
What helped me, was to put both shell file names into their absolute path:
´´´
app.post('/', function(request, respond) {
var inputValue = request.body.volume;
if (inputValue == "up") {
exec('sh /home/pi/server/volumeup.sh');
}
if(inputValue == "down") {
exec('sh /home/pi/server/volumedown.sh');
}
});
´´´
Bothered me for longer than I want to admit :-)
i am trying to get the socket id on the client side but for some reason it's not showing. Here is my code
client side
<html>
<head>
<meta charset="utf-8" />
<title>Ringneck</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
<script src="https://www.WebRTC-Experiment.com/RecordRTC.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io-stream/0.9.1/socket.io-stream.js"></script>
</head>
<body>
<div style="margin: 20px">
<h1 style="font-size: 18px;">Example 7: Media Translation Streaming</h1>
<div>
<button id="start-recording" disabled>Start Streaming</button>
<button id="stop-recording" disabled>Stop Streaming</button>
</div>
<h2 style="font-size: 16px; margin-bottom: 10px;">data.textTranslationResult.translation</h2>
<p>Record your voice in English, and see the German translation.</p>
<p>Keep recording for at least 4 seconds.</p>
<textarea id="results" style="width: 800px; height: 300px;"></textarea>
</div>
<script type="text/javascript">
const startRecording = document.getElementById('start-recording');
const stopRecording = document.getElementById('stop-recording');
let recordAudio;
const socketio = io();
console.log("JS file loaded"). // sanity check to make sure file is read
const socket = socketio.on('connect', function(msg) {
console.log("JS file loaded")
console.log("socket id: ",socket.id);
});
and my server side code
const express = require('express');
const cors = require('cors');
const path = require('path');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const port = process.env.PORT || 3000;
app.use(cors());
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/public/index.html'));
});
function onConnection(socket){
console.log(`Client connected [id=${socket.id}]`);
var returndata = {
"test":"yes"
}
socket.emit('server_setup', `Server connected [id=${socket.id}]`);
}
io.on('connection', onConnection);
http.listen(port, () => console.log('listening on port ' + port));
my server console log is
Client is connected [id=_RMXhb8Vz9XgSqhGAAGa]
but I could not get any response on the client side. what am i missing and how can i fix this and get the socket id ?
When I run your code, I found that there was a client-side Javascript parsing error on this line:
console.log("JS file loaded").
because of the period. When I replace that period with a semi-colon like this:
console.log("JS file loaded");
I get this output on the server:
Client connected [id=eoxspnNtoTg-2Kj3AAAB]
and this output in the debug console of the browser:
JS file loaded
socket id: eoxspnNtoTg-2Kj3AAAB
If you're not already doing so, you should be looking in the browser console for errors.
I am using Socket.io to create a multiplayer game. I have used a generated numerical code to dynamically create and join rooms.
My issue comes about emitting to specific rooms or even specific clients. I am unable to emit to a room (io.in(room).emit('event') or io.to(room).emit('event') They are synonyms). I am however able to socket.emit('event') between the server and client just fine. No errors. Simply nothing happens when I use anything but socket.emit(), io.emit(), and socket.on('',function(){ this.emit(); }).
The reason I have to emit to specific rooms is to update all clients in their rooms when a new client has joined. (I had tried emitting to each socket.id in each room but that does not work).
browser debugger tracking server emitted events
I have uploaded all the code I have used in my Node.js server in hopes that someone can see the error in my program. I am new to Socket.io and I am not sure about the validity of how I have set up my dynamic rooms.
The room event that does not work is: connectToRoom
Server
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/',function(req, res) {
res.sendFile(__dirname + '/client/index.html');
});
app.use('/client',express.static(__dirname + '/client'));
http.listen(3000, function(){
console.log('listening on localhost:3000');
});
io.on('connection', function(socket){
socket.id = Math.random();
SOCKET_LIST[socket.id]=socket;
socket.on('create',function(){
var thisGameId = ( Math.random() * 100000 ) | 0;
roomNo+=1;
roomArr[thisGameId]=thisGameId;
this.emit('createResponse', {gameId: thisGameId, mySocketId: socket.id});
this.join(thisGameId.toString());
});
socket.on('joinRoom',function(data){
//playerJoinGame(data);
//io.sockets.in(data.roomKey.toString()).emit('connectToRoom', "You are in room no. "+data.roomKey);
//socket.to(data.roomKey.toString()).emit('connectToRoom', "You are in room no. "+data.roomKey);
if( io.nsps['/'].adapter.rooms[data.roomKey]!== undefined ){
socket.join(data.roomKey.toString());
SOCKET_LIST[socket.id].username = data.username;
this.emit('joinRoomResponse',{
roomKey:data.roomKey
});
}
if(io.nsps['/'].adapter.rooms[data.roomKey]=== undefined){
this.emit('joinError',{
message: "This room does not exist."
});
}
});
socket.on('updateRoom',function(data){
var clients=io.sockets.adapter.rooms[data.roomKey].sockets;
var clientsArr=Object.keys(clients);
for (var clientId in clientsArr ) {
io.sockets.connected[clientsArr[clientId]].emit('connectToRoom', {
roomKey:data.roomKey,
username:data.username
});
}
io.sockets.in(data.roomKey).emit('connectToRoom', {
roomKey:data.roomKey,
username:data.username
});
});
socket.on('disconnect',function(){
delete SOCKET_LIST[socket.id];
});
});
Client
var socket = io();
var roomKey,username,mySocketId;
var optionDiv = document.getElementById('optionDiv');
var optionDivCreate = document.getElementById('optionDiv-create');
var optionDivJoin = document.getElementById('optionDiv-join');
var prepDiv = document.getElementById('prepDiv');
var createDiv = document.getElementById('create-Div');
var lobbyDiv = document.getElementById('lobbyDiv');
var createRoomKey = document.getElementById('create-roomKey');
var createPlayers = document.getElementById('create-players');
var joinForm = document.getElementById('join-form');
var joinForm_roomKey = document.getElementById('join-roomKey');
var joinForm_username = document.getElementById('join-username');
var joinForm_submit = document.getElementById('join-form-submit');
var gameDiv = document.getElementById("gameDiv");
optionDivCreate.onclick=function(){
socket.emit('create');
};
optionDivJoin.onclick=function(){
optionDiv.style.display='none';
prepDiv.style.display='inline-block';
joinForm.style.display='inline-block';
};
socket.on('createResponse',function(data){
roomKey = data.gameId;
mySocketId = data.mySocketId;
optionDiv.style.display='none';
prepDiv.style.display='inline-block';
createDiv.style.display='inline-block';
createRoomKey.innerHTML = roomKey;
});
joinForm_submit.onclick= function(){
};
joinForm.onsubmit = function(e){
e.preventDefault();
roomKey = joinForm_roomKey.value;
username = joinForm_username.value;
socket.emit('joinRoom',{
roomKey:roomKey,
username:username
});
joinForm_roomKey.value='';
joinForm_username.value='';
};
socket.on('joinRoomResponse',function(data){
optionDiv.style.display='none';
createDiv.style.display='none';
prepDiv.style.display='none';
lobbyDiv.style.display='inline-block';
socket.emit('updateRoom',{
roomKey:roomKey,
username:username
});
});
socket.on('connectToRoom',function(data){
socket.emit('debug');
//createPlayers.innerHTML = "<br />"+data.username;
alert("triggered");
});
socket.on('joinError',function(data){
alert(data.message);
});
HTML
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>Prototype</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="optionDiv" style="">
<button id="optionDiv-create">Create Game</button><br />
<button id="optionDiv-join">Join Game</button>
</div>
<div id="prepDiv" style="display:none;">
<div id="create-Div" style="display:none;">
Room Key:<br />
<h1 id="create-roomKey"></h1>
<h1 id="create-players"></h1>
</div>
<form id="join-form" style="display:none;">
Username:<br />
<input id="join-username" type="text" style="width:500px"></input><br />
Room Key:<br />
<input id="join-roomKey" type="text" style="width:500px"></input><br />
<button id="join-form-submit">Join</button>
</form>
</div>
<div id="lobbyDiv" style="display:none;">
You are in room:<br />
<h1 id="join-roomKey"></h1><br />
Players in room:<br />
<h1 id="join-players"></h1>
</div>
<div id="gameDiv" style="display:none;">
<div id="gameDiv-canvas">
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;">
</canvas>
</div>
<div id="gameDiv-chat">
<div id="chat-text" style="width:500px;height:100px;overflow-y:scroll">
<div>
Hello!
</div>
</div>
<form id="chat-form">
<input id="chat-input" type="text" style="width:500px"></input>
</form>
</div>
</div>
<!--<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.2/socket.io.js"></script>-->
<script src="/socket.io/socket.io.js"></script>
<script src="/client/js/client.js"></script>
</body>
</html>
The correct syntax is the following:
io.to('some room').emit('some event');
I have resolved my issue. The issue in this program is the way that I have made my program. The program is coded in a "non-dynamic room" manner. I have coded the program to only handle one game instance. Not multiple game instances for each room.
It is due to the fact that I am using one "game" instance for all the rooms. All games in each room will be using the same codes. Because I am running separate unique game instances for each unique room, I also need to create unique code for each corresponding game instance. This program does not create unique codes for each corresponding game instance. Hence it does not work.
I have restructured the program in a modular manner to handle activities for each individual room.
I have the following express app which just renders the sample.ejs page. On that page when I press the button the attached script changes the div text to
"THIS IS FROM J QUERY. I want the same thing to happen but I want the data to be coming from a database. In my express app if I try to use res.render(); every time I click the button then it reloads the page which I don't want. So is there a way to achieve this without reloading page and only update part of page?
I have searched stack overflow and the web but can't get an appropriate answer or maybe I just am unable to understand. I know this is a very basic thing to ask.
APP.js
var express = require('express');
var app = express();
app.use(express.static('public'));
app.use(express.static('./src/views'));
app.set('views', './src/views');
app.set('view engine' , 'ejs');
app.listen(3000 , (err)=>{console.log('Listening')});
app.get('/' , function(req , res) {
res.render('sample' , {result_from_database: res.body} );
});
sample.ejs
<!doctype html>
<html lang="en">
<head>
<title>Sample HTML File</title>
</head>
<body>
<div id="holder">
WELCOME
</div>
<form>
<button type="button" id="HButton"> HELLO </button>
</form>
</body>
<script>
$(document).ready(function () {
var form = $("#holder");
$("#HButton").on("click", function () {
form.html("THIS IS FROM J QUERY");
});
});
</script>
<script src="/lib/jquery/dist/jquery.js"></script>
</html>
Now this is what I want to do
<!doctype html>
<html lang="en">
<head>
<title>Sample HTML File</title>
</head>
<body>
<div id="holder">
<%= result_from_database %>
</div>
<form>
<button type="button" id="HButton"> HELLO </button>
</form>
</body>
<script>
$(document).ready(function () {
var my_div = $("#holder");
$("#HButton").on("click", function () {
/* Tell app.js that I clicked a button and then app.js
query the database and using ejs or something else update the
my_div inner html with the database result without
reloading page */
});
});
</script>
<script src="/lib/jquery/dist/jquery.js"></script>
</html>
NOTE: I'm not asking how to query the database
-Thanks
You have to define and endpoint in your back end that return the information you want to display:
app.js
var express = require('express');
var app = express();
app.use(express.static('public'));
app.use(express.static('./src/views'));
app.set('views', './src/views');
app.set('view engine' , 'ejs');
app.listen(3000 , (err)=>{console.log('Listening')});
app.get('/' , function(req , res) {
res.render('sample' , {result_from_database: res.body} );
});
app.get('/api/books', function(req, res) {
res.json({
message: 'Your database information'
});
});
then on your front end you need to make a call to api endpoint like:
sample.ejs
<script>
$(document).ready(function () {
var my_div = $("#holder");
$("#HButton").on("click", function () {
$.ajax({
url: "/api/books"
})
.done(function( data ) {
console.log( "Sample of data:", data );
$('#holder').html(data.message);
});
});
});
</script>
You can find more information on ajax call with jquery here.
However i would suggest you to use any framework like angular or react to make it easier to render the data in your html, otherwise you will have to write a lot of code using jquery.
When I load index.html on port 3000 and when I click on play button, all the messages are sent properly, but the ('#pause').click() is not being executed because the audio does not pause.
index.html code:
<html>
<head>
<script type="text/javascript" src="new.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="jquery-3.1.1.min.js"></script>
</head>
<body>
<button type="button" id="play" name="play" value="play">PLAY</button>
<button onclick="pauseAd()" type="button" name="pause" value="pause">PAUSE</button>
</br>
<audio controls id="song">
<source src="Lyrics to Swallowed in the Sea - Coldplay.mp3" type="audio/mpeg">
</audio>
<div id="messages"></div>
<script>
var socket = io.connect("http://localhost:3000");
$(function() {
$('#play').bind('click', function() {
alert("User clicked on play");
playAd();
socket.emit('msg', {
sent: 1
});
return false;
});
});
socket.on('msg-received', function(data) {
if (data.value == 1) {
$('#pause').click();
$('#messages').append('<p>message received' + data.value + '</p>')
}
});
</script>
</body>
</html>
Server code:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use(express.static('./Public'));
app.set('views', __dirname + '/tpl');
app.set('view engine', "jade");
app.engine('jade', require('jade').__express);
app.get("/", function(req, res) {
res.render("new");
});
io.sockets.on('connection', function(socket) {
console.log("user connected");
socket.on('msg', function(data) {
console.log("message received", data);
socket.emit('msg-received', {
value: 1
});
});
});
http.listen(3000, function() {
console.log('listening on *:3000');
});
The $('#pause') is JQuery's selector for the element with the id attribute of pause. You currently don't have an element with the id attribute of pause, so $('#pause') currently returns nothing.
To fix your problem, all you need to do is add the attribute id='pause' to your pause button, which becomes:
<button id='pause' onclick="pauseAd()" type="button" name="pause" value="pause">PAUSE</button>
This will have JQuery select the button when you select the elements with the id of pause
Hope this helped and if you need further clarification let me know.