I am currently working at a nodeJS robotics app and i am trying to use sockets.io in order to show some messages and data in browser.
I have the following nodeJS code:
app.get('/', function(req, res){
res.sendfile('index.html');
});
io.on('connection', function(socket){
console.log('A user connected');
socket.on('clientEvent', function(data){
function take_tool() {
while(!take_tool_flag) {
if(fs.existsSync('D:/flag.txt')) {
fs.writeFileSync('D:/input_robot.txt', '-1');
socket.emit('testerEvent', 'Robot is taking the writing tool!');
console.log('Robot is taking the writing tool!');
fs.unlinkSync('D:/flag.txt');
take_tool_flag = true;
}
}
}
function draw_table() {
while(!draw_table_flag && take_tool_flag) {
if(fs.existsSync('D:/flag.txt')) {
fs.writeFileSync('D:/input_robot.txt', '-3');
socket.emit('testerEvent', 'Robot is drawing the table game!');
console.log('Robot is drawing the table game!');
fs.unlinkSync('D:/flag.txt');
draw_table_flag = true;
}
}
}
function game() {
socket.emit('testerEvent', 'A new game has started!');
console.log("A new game has started!");
fs.writeFileSync('D:/input_robot.txt', '-99');
if(!take_tool_flag) { take_tool(); }
if(!draw_table_flag) { draw_table(); }
}
game();
});
socket.on('disconnect', function () {
console.log('A user disconnected');
});
});
http.listen(3000, function(){
console.log('listening on localhost:3000');
});
And then in HTML:
<!DOCTYPE html>
<html>
<head><title>Hello world</title></head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('testerEvent', function(data){document.write(data)});
function start() {
socket.emit('clientEvent', 'Sent an event from the client!');
}
</script>
<body>Hello world
<button onclick="start()">Start</button>
</body>
</html>
When i press the start button from html the first 3 instructions from game(); function are executed:
socket.emit('testerEvent', 'A new game has started!');
console.log("A new game has started!");
fs.writeFileSync('D:/input_robot.txt', '-99');
and i get the message in browser from socket.emit;
Then it enters in take_tool(); function where it waits for 'D:/flag.txt' to be created. When i create this file the execution of take_tool(); continues but i don't get in browser the message from socket.emit. Same thing for draw_table(); function. I receive those messages instead at the end of game(); function execution. I need those messages to be shown in browser in real time not at the end of function execution. What seems to be the problem? Thank you!
Related
I made a chat room using electron. But when I send a message to the server and from there the message will be displayed to the users for some reason the message is being displayed multiple times. Example: I send -> "hello" the message will be displayed once, when I send a second message ->"Hello server" the message will be display two times, when I sent a third message ->"ok" this message will be displayed three times. The fourth message will be displayed 4 times etc.
this is the renderer.js code:
const ws = new WebSocket("ws://127.0.0.1:5000");
ws.addEventListener('open', function(event){
ws.send('hello server');
console.log("data sent");
});
function send_data(){
console.log("button clicked");
ws.send(document.getElementById("input_text").value);
ws.addEventListener('message', function(event){
console.log("server send something");
let mess=event.data;
console.log(mess);
update_chat(mess);
});
};
function update_chat(mess){
const div = document.createElement('div');
div.classList.add('message');
div.innerHTML = `okwpegjwpgj said: ${mess}`;
document.querySelector('.chat_messages').appendChild(div);
}
this is the server.js code:
const WebSocket = require('ws');
let broadcast_msg;
const PORT = 5000;
const wss = new WebSocket.Server({
port: PORT
});
wss.on("connection", ws =>{
ws.on('message', function incoming(message){
broadcast_msg=message;
console.log('received: ', message);
ws.send(message);
});
});
console.log("Server is liestening on port " + PORT);
Because you add the addEventListener('message') on every send_data() call.
Add the eventlistener once and remove it from the send_data() method. you don't need to add a new eventlistener every time you send data.
ws.addEventListener('message', function(event){
console.log("server send something");
let mess=event.data;
console.log(mess);
update_chat(mess);
});
function send_data(){
console.log("button clicked");
ws.send(document.getElementById("input_text").value);
};
Change your renderer.js file to this:
const ws = new WebSocket("ws://127.0.0.1:5000");
ws.addEventListener('open', function(event){
ws.send('hello server');
console.log("data sent");
});
ws.addEventListener('message', function(event){
console.log("server send something");
let mess=event.data;
console.log(mess);
update_chat(mess);
});
function send_data(){
console.log("button clicked");
ws.send(document.getElementById("input_text").value);
};
function update_chat(mess){
const div = document.createElement('div');
div.classList.add('message');
div.innerHTML = `okwpegjwpgj said: ${mess}`;
document.querySelector('.chat_messages').appendChild(div);
}
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
})
I might missing something basic, but here is my goal: I have a small instant chat example based on tutorial found here Instant Chat for drupal
The principle is to connect to a nodejs server that basically just broadcast all messages it receives.
I have this function on the client side (inside a drupal tpl.php file):
(function($) {
var myNick = 'me';
var socket = io.connect('http://<?php print $_SERVER['SERVER_ADDR'] ?>:8081');
socket.on('connect', function() {
$('#chat').addClass('connected');
});
socket.on('user message', message);
function message(from, msg) {
if (msg == 'GO') {
** EXECUTE A FUNCTION HERE **
} else { //display the message and sender
$('#lines').append($('<p>').append(from, msg));
}
}
$(document).ready(function() {
$('#send-message').submit(function() {
message(myNick, $('#messageinput').val());
socket.emit('user message', $('#messageinput').val());
clear();
$('#lines').get(0).scrollTop = 10000000;
return false;
});
function clear() {
$('#message').val('').focus();
};
});
})(jQuery);
When I send a message with content =GO, the submit is executed, the message(..,..) function is called and my specific function is executed properly.
But when I receive a GO message, the socket.on event triggers, message() function is called, but my specific function is NOT executed.
Any Idea how I can fix this?
Many thanks for your help.
Michael.
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.
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');
});