Wait for Electron window to be a specific URL? - node.js

So I am writing an application in Node.js and Electron, and I am trying to login through Google on the same session, then get another URL. I have the session working and the login to Google working, but when I login to Google, I want it to switch and load another URL. The current idea I have is something like this:
win.loadURL('https://accounts.google.com/').then(() => {
});
setInterval(() => {
while (!win.webContents.getURL().includes("myaccount.google")) {
if (win.webContents.getURL().includes("myaccount.google")) {
break;
}
}
clearInterval();
}, 100);
win.loadURL('http://' + url);
I just don't know what else to do, I know this is fairly spaghetti but I've tried so many things and nothing seems to work correctly. I feel like I shouldn't even be doing a while loop at all because it seems to freeze my browser (understandably).

Listen for the event 'did-navigate'. I would like to but I can't test this for you at this time.
Also: electron webview navigation event

Related

Streaming html5 animation in real time from server to client

I have an animation written in Javascript. I am new to nodejs (no knowledge) and I have been finding it difficult to stream the animation in real-time to users connected to the site.
I read about socket.io and Websockets but I do not have a good approach. Currently, the animation starts with a function call and writes to a canvas.
I need to know how to stream this animation from the server-side to the client so that multiple connected users can see the same scene of the animation at the same time. A functional explanation with code will also be appreciated.
Without knowing what type of animations are used, how they're built and work, I would suggest doing the animation client-side and just send some sort of synchronization command from server to all clients using socket.io .
I also would suggest putting all users (which all should see the same animation) in to one room (see rooms).
Now you can send a synchronized command to all users, e.g. to start, continue, stop and reset the animation. On the other hand, on the server-side you could track which of the clients in the room have already loaded the animation, started, stopped and so on.
// server
io.to('some-room').emit('load', animationid);
/* ... */
socket.on('loaded', () => {
if (allClientsLoaded) {
io.to('some-room').emit('start');
}
});
socket.on('started', () => {
});
// client
socket.on('load', async (animationid) => {
await loadAnimation(animationid);
socket.emit('loaded');
});
socket.on('start', () => {
startAnimation();
});

Send request progress to client side via nodejs and express

I am using this (contentful-export) library in my express app like so
const app = require('express');
...
app.get('/export', (req, rex, next) => {
const contentfulExport = require('contentful-export');
const options = {
...
}
contentfulExport(options).then((result) => {
res.send(result);
});
})
now this does work, but the method takes a bit of time and sends status / progress messages to the node console, but I would like to keep the user updated also.. is there a way I can send the node console progress messages to the client??
This is my first time using node / express any help would be appreciated, I'm not sure if this already has an answer since im not entirely sure what to call it?
Looking of the documentation for contentful-export I don't think this is possible. The way this usually works in Node is that you have an object (contentfulExport in this case), you call a method on this object and the same object is also an EventEmitter. This way you'd get a hook to react to fired events.
// pseudo code
someLibrary.on('someEvent', (event) => { /* do something */ })
someLibrary.doLongRunningTask()
.then(/* ... */)
This is not documented for contentful-export so I assume that there is no way to hook into the log messages that are sent to the console.
Your question has another tricky angle though. In the code you shared you include a single endpoint (/export). If you would like to display updates or show some progress you'd probably need a second endpoint giving information about the progress of your long running task (which you can not access with contentful-export though).
The way this is usually handled is that you kick of a long running task via a certain HTTP endpoint and then use another endpoint that serves infos via polling or or a web socket connection.
Sorry that I can't give a proper solution but due to the limitation of contentful-export I don't think there is a clean/easy way to show progress of the exported data.
Hope that helps. :)

Node.js Express slowing down after 5 requests

I've come across a strange issue in my app (Node.js/jQuery/Mongo/Express setup) where connections are slowing down after 5 attempts.
I have a page that has 10 items on, all when clicked proceed to open a lightbox, with then in turn grabs data from the database. If I click a button to open the lightbox it will show information fine, until you've opened/closed the lightbox about 6 times.
I'm running v9.0.0 of Node, and I've got maxSockets to Infinity.
My route:
app.get('/active-item', function(req, res) {
if (typeof req.headers.referer !== 'undefined') {
if (req.session.user!==undefined) {
res.render('pages/active-item', { user: req.session.user, email_address: req.session.user.emailAddress });
} else {
res.render('pages/active-item');
}
} else {
res.redirect('/');
}
});
On the 6th attempt it just doesn't load the data in the lightbox and then after about 10-20 seconds, I see the requests come through my logs on Express. Very strange issue, I thought it was a maxSockets issue but it doesn't seem so.
I've seen similar issues online but all seems to be solved by setting maxSockets to Infinity. Am I leaving a connection open on my route? I can't possibly think what else I haven't covered.
Any ideas?

How to catch when a user leaves the page in Meteor and/or Iron router?

I'm trying to catch when a user leaves from my Meteor application (version 1.2.0.2) ; something equivalent to the SocketIO disconnect() on the server side.
The user could close his browser, go to another website or simply refresh the page and it would fire anyway
Surprisingly, i'm searching on Internet and everything is mixed up, nothing works properly. I thought Meteor was literally based on this magic-live processing so it must manage this event in a way or another.
Iron router documentation specify this :
onStop: Called when the route is stopped, typically right before a new
route is run.
I also found Router.load and Router.unload but none of them work. This is my current [not working] code which is quite simple
Router.configure
layoutTemplate: 'MasterLayout'
loadingTemplate: 'Loading'
notFoundTemplate: 'NotFound'
Router.onStop (->
console.log('Try to stop')
Users.insert({
name: "This is a test"
lat: 0
lng: 0
})
)
Am I doing something wrong here ? How do you catch this event in my app ?
You need to attach to the onStop of the route, not the router. For instance:
Router.route('/', {
onStop: function() {
console.log("someone left the '/' route");
}
});
Another option is to use the onStop event of subscriptions. That is probably the option most similar to the socketio disconnect you mentioned. You can find an example of that in the typhone source code.
There were two solution working, I found the 2nd and best one by searching in the API Documentation for a while.
First solution : working with subscribe & publish
Anywhere in the controller / front-end side you must subscribe to a collection
# in coffee
#subscribe('allTargets')
# in javascript
this.subscribe('allTargets')
Afterwards you just have to publish and add a onStop listener. This example will take a Targets collection I already defined somewhere before, it just gets all the entries.
# in coffee
Meteor.publish 'allTargets', ->
#onStop ->
# Do your stuff here
return Targets.find()
# in javascript
Meteor.publish('allTargets', function() {
this.onStop(function() {
// Do your stuff here
});
return Targets.find();
});
You have to be careful not to return Targets.find() before you set the onStop listener too. I don't think it's a perfect solution since you don't listen to the connection itself but the changes of a collection.
Second solution : working with DDP connection
I realized through the Meteor API Documentation we can directly listen to the connection and see if someone disconnect from the server-side.
To stay well-organized and clean within my Meteor Iron project I added a new file in app/server/connection.coffee and wrote this code
# in coffee
Meteor.onConnection (connection) ->
connection.onClose ->
# Do your stuff
# in javascript
Meteor.onConnection(function(connection) {
connection.onClose(function() {
// Do your stuff
});
});
You can manage datas with connection.id which's the unique identifier of your browser tab. Both solutions are working well for me.
If you use Meteor.userId through their accounts system, you can't use it outside a method in the server-side so I had to find a workaround with the connection.id.
If anyone has a better solution to manage connections while getting this kind of client datas, don't hesitate to give your input.

After browser refresh I can't emit to specific client anymore?

My code looks something like this:
io.sockets.on('connection', function(socket) {
player.on('updatePlayer', function(err, result) {
if(result) {
console.log("UPDATING PLAYER");
io.sockets.socket(socket.id).emit('updatePlayer', { player: player });
}
});
}
When I first start the server and load the website everything works fine. If I do an action that triggers the "updatePlayer" event my console looks like this:
UPDATING PLAYER
debug - websocket writing 5:::{DATA IM SENDING}
After I refresh the page, or close it and reload again I only get:
UPDATING PLAYER
Anyone has any idea why the socket doesn't emit anything at all?
It seems to ignore
io.sockets.socket(socket.id).emit('updatePlayer', { player: player });
The problem occurs because when you first visit the page after server start, you register updatePlayer event, and this callback "remembers" the current socket object.
Then you reload the page, that updatePlayer event fires, and its callback tries to access socket that was "remembered". That socket refers to your previous connection that is lost after page reload. That's why it can't send the message.
To solve this problem you have to declare all the variables, that connected somehow with player object, inside io.sockets.on('connection') callback.

Resources