Nodejs, express & socket.io communicate between two static client pages - javascript

i am trying to build a remote for a gallery by using nodejs, express & socket.io.
the structure is as follows
/index.js
/public/screen.html
/screen.js
/remote.html
/remote.js
the idea is to have a gallery of images displayed on remote.html, select one and send the selected index to screen.html by using socket.io.
as of now my code looks like this:
index.js
var express = require('express');
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io').listen(server);
app.use(express.static('public'));
server.listen(8080, function(){
// setup image gallery and stuff...
connectToServer();
});
remote.js
var socket = null;
document.addEventListener("DOMContentLoaded", function(event) {
//some stuff
connectToServer();
});
function showImage (index){ //called by events
console.log('selected incdex: ' + index);
if(socket != null) {
socket.emit('selection', {id: index});
};
}
function connectToServer(){
socket = io.connect('http://localhost:8080');
socket.on('connection', function (socket) {
var text = document.querySelector('#name');
socket.emit('newRemote', 'new remote connected');
console.log('emitted welcome');
socket.on('newScreen', function (data) {
console.log(data);
});
});
}
screen.js
var socket = null;
document.addEventListener("DOMContentLoaded", function(event) {
//some stuff
connectToServer();
});
function connectToServer(){
socket = io.connect('http://localhost:8080');
socket.on('connection', function (socket) {
var text = document.querySelector('#name');
socket.emit('newScreen', { name: name });
socket.on('newRemote', function (data) {
console.log(data);
});
});
};
when starting with node index.js i get
listening on *:8080
and when loading screen or remote.html i get
debug - client authorized
info - handshake authorized MwtGFRCZamcyKkUpK5_W
as I see it: somehow a connection is established, but:
no messages are sent / received on both ends
no logs are printed to the console for the connection events
any idea why nothing is happening?

It appears that you have mixed server-side code into your client. The 'connection' event is an event that needs to be listened to on the server, not your client files. Additionally, you cannot directly call client-side functions from your server-side code.
The below code does not work:
server.listen(8080, function(){
// setup image gallery and stuff...
connectToServer();
});
To achieve the above you will need to put the following code on your server:
server.listen(8080, function(){
socket.on('connection', function (socket) {
// setup image gallery and stuff...
socket.emit('connectToServer', myPassedParameters);
});
});
And the following listener for that event on the client:
socket.on('connectToServer', function (myPassedParameters) {
var text = document.querySelector('#name');
// stuff for client side here
});
});
In addition to the above, you cannot do calls from one client file to another client file using socket.io. You would have to do a call to the server first and then call a function on the other file once it has been loaded for the user.

Related

Why Websocket connection is disconneting after sending message on iOS 15 devices?

I am building a website based on web socket communication. Its is working fine until iOS 14 but started breaking from iOS 15. Web socket java script client is able to open connection to server, but upon trying to send a message, the connection is getting closed. Following is my html and JS code.
function start_websocket() {
connection = new WebSocket("wss://localhost/wss/");
connection.onopen = function () {
console.log('Connection Opened');
};
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
connection.onclose = function(){
console.log("Closed");
};
connection.onmessage = function (e) {
console.log("Message Received :" + e.data);
};
}
function myFunction() {
var testText = document.getElementById("testText");
if (testText.value != "" && connection.readyState === connection.OPEN) {
connection.send("Test");
}
}
start_websocket();
myFunction() is an on-click event of a button.
A Java Websocket server is used, which will decode and send the messages based on the Data framing in https://datatracker.ietf.org/doc/html/rfc6455#section-5.
Saw different articles on the Web, but didn't found a solution to this issue. Any suggestions are much appreciated. Looking forward for your answers
Thanks in advance.

setInterval running more times than intended?

I have an application written in node.js using socket.io. The main event loop looks like this:
io.on("connect", function(CLIENT) {
//Run this code when a client connects
SERVER.connectPlayer(CLIENT);
//Recieve input from client
SERVER.handleInput(CLIENT);
//Run this code when a client disconnects
CLIENT.on("disconnect", function() {
SERVER.disconnectPlayer(CLIENT);
});
});
function main() {
SERVER.update();
}
setInterval(main, SERVER.tickRate);
This works fine, but I'm having an issue with SERVER.handleInput:
//Recieve input from the client
Server.prototype.handleInput = function(client) {
client.on("sendKey", function(data) {
client.player.handleKey(data.key, data.pressed);
});
client.on("sendMouse", function(data) {
client.player.mouse_x = data.x;
client.player.mouse_y = data.y;
});
}
Both of these work fine, but the second method client.on("sendMouse") triggers my main() loop above whenever it is run. I've tried commenting out the body of sendMouse but that doesn't change anything.
This method is being triggered by the client whenever the user moves the mouse. This is the code I'm using:
//Handles input on the client and sends it to the server
Game.prototype.bindKeys = function() {
var game = this;
this.input = {};
document.addEventListener("mousemove", function(event) {
game.mouseMove(event);
}, false);
}
Game.prototype.mouseMove = function(event) {
this.setMousePos(event);
client.emit("sendMouse", this.mouse);
}
setMousePos just figures out the current position of the cursor and sets it so that the client knows what coordinates to send back to the server. If I remove sendMouse on the client the game runs perfectly but otherwise my main setInterval loop is being run additionally every time sendMouse triggers.
I have no idea what would cause this. The keyboard input works perfectly fine. I'd greatly appreciate any advice.

socket.io, getting io is not defined on console

I am setting a basic chat app using sockets, but in the initial stage of programming I am getting this error: “io is not defined” on the client side.
I have tried including the CDN and adding
<script src="/socket.io/socket.io.js"></script>,
but no success.
HTML
<head>
<script src="jquery-3.2.1.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="script.js"></script>
</head>
script.js
let socket = io();
console.log("socket formed on " + socket.id)
server.js
const express = require('express')
const path = require('path')
const socketio = require('socket.io')
const http = require('http')
const app = express();
const server = http.createServer(app)
const io = socketio(server)
app.use('/', express.static(path.join(__dirname, 'frontend')))
io.on('connection', (socket) => {
console.log("New socket formed fksrom " + socket.id)
})
server.listen(2345, () => console.log('website open on http://localhost:2345'))
I expect the socket ID to be shown in the console,
but on console it is displaying “io is not defined”.
I think you should check if document has loaded so here's the code below:
// Pure Javascript
if(document.readyState === "complete") {
//Already loaded!
}
else {
//Add onload or DOMContentLoaded event listeners here: for example,
window.addEventListener("onload", function () {/* Move your code here */}, false);
//or
//document.addEventListener("DOMContentLoaded", function () {/* code */}, false);
}
Since you already have jQuery:
$(document).ready(function(){
/** Your code here */
})
You're trying to access a script before it is loaded so the above code should help you run your script only when you've done with loading the jQuery library and socket.io.js library.

How do I trigger javascript from a button click

I'm trying to trigger javascript to start, stop and restart a stopwatch from a button in the html file. What is the best way to pass an event from the html to the javascript?
I have managed to trigger a console log when the button is pressed, but I can't put in the javascript in the second js file. I just receive errors. Would socket.io work? I have investigated Event emitters and listeners but I think it's out of my skill level.
server.js
var express = require('express');
var app = express();
var path = require('path');
var Stopwatch = require("node-stopwatch").Stopwatch;
const EventEmitter = require('events');
var stopwatch = Stopwatch.create();
app.use(express.static('public'));
// start the express web server listening on 8080
app.listen(8080, () => {
console.log('listening on 8080');
});
// serve the homepage
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
stopwatch.start();
/*
stopwatch output test
*/
console.log("ticks: " + stopwatch.elapsedTicks);
console.log("milliseconds: " + stopwatch.elapsedMilliseconds);
console.log("seconds: " + stopwatch.elapsed.seconds);
console.log("minutes: " + stopwatch.elapsed.minutes);
console.log("hours: " + stopwatch.elapsed.hours);
//stop it now
stopwatch.stop();
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
client.js
console.log('Client-side code running');
const button = document.getElementById('myButton');
button.addEventListener('click', function(e) {
console.log('button was clicked');
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Stopwatch</title>
</head>
<body>
<h1>Stopwatch</h1>
<p id="counter">Loading button click data.</p>
<button id="myButton">Click me!</button>
</body>
<script src="client.js"></script>
</html>
I expected to trigger the javascript on button click but I cannot run it in client.js
Use in the client.js
window.addEventListener("load", myFunction);
and place your code to myFunction
If this console is printed, console.log('Client-side code running');
Try to add your button event inside a function.
function onLoadBody() {
const button = document.getElementById('myButton');
button.addEventListener('click', function(e) {
console.log('button was clicked');
});
}
<body onload="onLoadBody()" >...
let say you have two files, client.js and server.js
You can use socket.io for quicker response as apposed to HTTP request
You just need to emit a key to the server and the server will respond to that emit.
Client.js
let socket = io();
socket.emit('start')
Server.js
socket.on('start',(data)=>{
// do what ever you want and send back to client with the same emit method
// `socket.emit()` sends message to connected client
// socket.broadcast.emit() send message to all clients except you
// io.emit() send message to all including you
})

socket.on() not receiving data

I am having a problem with getting socket.on to work
$('#showmsg').click(function() {
var socket = io.connect('http://localhost:3000');
var msgText = $('#msgtext');
socket.emit('show msg', msgText.val());
});
That code works, as shown by using
io.sockets.on('connection', function(socket) {
socket.on('show msg', function(data) {
console.log(data);
});
});
in server.js, my main app file, however in another file, when I use the code
$(document).ready(function (){
var socket = io.connect();
socket.on('show msg', function(data) {
$('#container').hide();
});
});
Nothing happens. Does anyone know how I can get this code to work?
When you connect in the client, you have to wait for the connect message before you can send data with .emit(). As you have it now, you are trying to send the data before the connection has finished so the data is lost.
See the client-side example here: http://socket.io/docs/#sending-and-getting-data-(acknowledgements)
I think what's happening is that in your document.ready function, you are trying to call io.connect() but you are then calling the show message before your socket has connected. Try doing it like this
socket.on('connect', function (){
socket.on('show msg', function(data) {
$('#container').hide();
});
});
Nothing happens because you don't emit anything.
$(document).ready(function (){
var socket = io.connect('http://localhost:3000');
socket.on('show msg', function(data) {
$('#container').hide();
});
socket.emit('show msg', 'right now I am emitting data');
});

Categories