Client side code updating server side code - javascript

I have deployed a simple javascript memory game to heroku with lite-server.
https://happy-birthday-eline.herokuapp.com
To my surprise, when a user turns a card, all other users see the card turn too. I can't figure out why. I thought client-side actions were limited to the client and could in no way update the server or impact other users.
How do I prevent a user action (click on card) from propagating to all other users?
Thanks
Answer: I thought I could just deploy using lite-server (rather than express) but lite-server has file listening enabled, which is why user actions were impacting all other users. (Obvious) solution was to use express on Heroku, not lite-server!

It's caused by BrowserSync. Looks like you deployed a development version of your code and BrowserSync is connected.
In order to avoid it, you have to deploy a production version of your application.

Related

Remotely force kill a shared ngrok session forwarding a React app

I share an ngrok account with my coworkers. We are using it to develop a React application (npx create-react-app). We are all using UNIX-like systems. Quite often I go to spin up an http tunnel and I am met with the message
Your account '*****#*********.com' is limited to 1 simultaneous ngrok client session.
Active ngrok client sessions in region 'us':
- ******************************** (**.***.***.***)
ERR_NGROK_108
Or if I am logged in with my own account, but trying to use the same tunnel, I get
The tunnel 'https://*****.ngrok.io' is already bound to another
tunnel session
ERR_NGROK_334
Both of these messages mean my coworker (who I know for a fact is currently asleep) left their ngrok session running. I would like to execute a simple command that tells their system to kill ngrok processes.
Is there an ngrok CLI command to force kill a session running on another machine?
Based on my research so far, I think the answer is no. But please tell me if I am wrong.
Is there a safe way to remotely execute a system command to kill ngrok sessions?
I found a beautiful solution that some Rails developers came up with to remotely kill ngrok sessions in a Rails API.
Their strategy is to include an API endpoint (only in development mode) that executes the system command killall ngrok to kill all ngrok processes on that system.
Is there a way to remotely execute system commands with our client-side rendered React application?
My gut tells me no, at least not without spinning up a server to receive the kill request.
My thought is, maybe I can create a proxy server for my React application using Node and Express. That server can do exactly two things: act as a proxy to the React app, and kill ngrok when it receives a specific request. In the past I have built a proxy server in the same git repository as my React app, so I think this solution is attainable.
How would you recommend I move forward?
So far I have not been able to find an example of this online. I would hate to waste my time building a low quality version of something that already exists.
I see there is an ngrok npm package... maybe that could be useful.
Any thoughts on best practices when configuring/coding the proxy server are much appreciated.
Or if you think I am overcomplicating things, let me know.
Thanks!
Ngrok now has a beta API (for paid plans only I believe?) that can remotely stop agents. Their dashboard now also offers the same functionality, even if you are not part of the beta.

Edits to Express routes are being ignored

I recently moved a web app I was working on locally to a server. When working locally, any changes I would make to my express routes would be reflected. As soon as I moved the app to the server, I noticed that I could comment out every line of code pertaining to my routes, e.g. app.get('/') etc.
but those changes would never be reflected, i.e. I would still be served files as if the first version of the website I transferred was still in effect.
Something that is weird, is that any changes not pertaining to routes is taken into consideration, so if I console.log outside of a middleware it will print.
Any idea on how to make sure that express takes into consideration my changes to its routes?
EDIT:
I figured out the issue: somehow, the browser was fetching from localhost even when I was using the remote server's domain (really weird).
As soon as I stopped listening on my local machine, the browser started to make requests to the server.
Guess your host isn't doing any new BUILDS. Check is there's any way to stop process and run the build again.
If you're hosting it on VPS then you can stop all process with SIGTERM or something alike

Meteor app loses connection to MongoDB due to large(ish?) traffic

I started learning meteor recently and I am developing an application that is similar to a bus timetable app; I have several screens (about 30 devices with browsers) and I connect them all to one localhost that runs my application on cmd (the app is offline using windows 10 with local MongoDB, no online server). Each set of screens display a relevant bus and its timetable, extracted from a MongoDB collection.
The app used to work just fine, but when I added 10 more screens, the clients seem to be disconnected from the server after a couple of minutes; I have meteor calls that display server time on screen, this time shows up as undefined when the server drops and I can't see any of my collections' documents via MeteorToys, I see the collections, but the documents are 0. Also, I can't log in to my admin page (which is a basic user interface that I made, simple MongoDB Accounts collection)
It's worth mentioning that the whole app does not crash; I can still navigate to my pages as my layout, HTML and CSS, still show up, just my server-related functionalities that stop.
I realize it's a traffic issue, as when I disconnect all of the screens and run the app, it works just fine. Also, when I reconnect one by one, it also seems to work fine.
I get no error on my console on the client, and on the server CMD, the application does not crash, it stays on with no error what's so ever.
Also, I added Meteor.status() ping to my console every second, and I get this
{status: "connected", connected: true, retryCount: 0}
which means technically the server is not offline?
I'm very lost, what can I do to rectify this?
Update:
I noticed that I had several ServerSessions that run on every second that get my time from the server. I changed them to normal Sessions and I'm now facing a different issue; I think there is a memory leak somewhere; when it freezes I noticed my RAM usage skyrocketed to 8GB (I have my max_old_space set to 8912 so it shouldn't be a problem) The normal usage was about when it runs is around 600-900MB
Then I get FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
=> Exited with code: 3
and Server Unreachable on the browser with 503 (Service Unavailable)
The server then restarts, and it does the same thing. Help :(
I experienced the same behavior with an app loading lots of data and doing computations. When the nodejs server CPU is on load, the app looses connexion to its node back end, and when the database server CPU is on load, the app looses connexion to the database.
Here are some advices:
Start by this reading if you haven't : https://bulletproofmeteor.com/ It has been written some years ago but still a lot of good practices inside
Monitor your app on your machine, try to understand what is the bottleneck: data transfers, disk reads, cpu intensive tasks ?
Look into your publication/subscription model. You may send too much data to the client, maybe you can limit the amount of data needed ?
if your setup is critical, don't run it on a single windows machine using the meteor command ! : start with building a proper nodejs app using meteor build https://guide.meteor.com/build-tool.html
use nginx to handle incoming connexion, it is robust and scalable
use a separate host for the database, and maybe a mongo replica set of 3 machines (this may solve your issue by giving more database availability, but I haven't tested yet)
Edit regarding the build: After building the app, you will obtain a folder. Here are the steps to launch the app in production mode:
cd into your meteor app folder
meteor build targetFolder --directory
cd targetFolder/bundle
(cd programs/server && npm install)
meteor node targetFolder/main.js #I use meteor node to ensure version compatibility

How to deploy a program with a separate server and client code?

I recognize this question is ridiculously stupid but I need an answer to this. I have tried going through google for an answer to this, but no luck so far.
So, I am going to build an application in JavaScript (using React and Redux) with separate client and server logic. The code for each will be housed in separate files. If I deploy both my server and client code logic to heroku, how will it be deployed by heroku?
By my understanding, heroku deploys a single app, and it will see this as essentially two different apps. Do I need to write both client and server logic together and push them up to Heroku necessarily?
Without an example of what you are trying to do with your app it is quite hard to give a correct answer.
But if you want to use Heroku node.js you will be deploying both server and client logic in one project.
Here is an example for react.js: http://ditrospecta.com/javascript/react/es6/webpack/heroku/2015/08/08/deploying-react-webpack-heroku.html

While the meteor app is running, what are some ways of executing arbitrary code on the server side?

Sometimes I find myself wanting to execute some privileged code on the server while the app is running. For example, I may want to quickly delete a document in a collection (when the client-side is blocked from doing so). Or, I may want to quickly try out server-side functions like Email.send and Accounts.createUser.
So what are some of the ways of achieving this? I'm concerned with both cases of how an meteor app can be run:
running using the meteor command
running as the bundled node app
Ultimately, I'd also like to setup cron jobs that can execute some code in the Meteor context. Is this directly achievable or doable through workarounds?
Thanks for the help!
Couldn't you just write server-side methods that only work for your user? Then expose those with Meteor.methods and run them in the client console. That's what I do when I want to test eg. Email.send. You could also go a step further and write a rudimentary admin UI.
For instance, on the server:
Meteor.methods({
test_sendEmail: function(options) {
if (this.userId != adminUserId) return; // don't execute unless admin
Email.send(options);
}
});
On the client:
Meteor.call("test_sendEmail", {to: "foo#bar.com", subject: "Foo", text: "Bar"});
To interact with the database while your app is running, you can do meteor mongo in the root directory of your app. This will start a mongo shell, but you can't test server-side functions in it. As of now, I don't think there's a way to actually run a server-side console in a (not bundled) meteor app, but maybe you can meteor bundle your app, run it with node, and then find a way to start a server-side console.
You could invoke meteor server side code by simulating a browser using curl. If you launch meteor every time, you will have to put your code into a Meteor.startup() function. If you simulate a browser, you could leave the meteor server running, and then specify arbitrary functions to execute based on forms or querystrings.
You can also do Meteor.methods({eval: function(code){eval(code);}}), which allows you to type in whatever code you want and run it server-side. It's not the most secure thing in the world, but it worked for me. My guess is it's possible to make it somewhat less insecure by making sure that the user with this.userId in the method is an admin. Here's a repo for testing, feel free to clone and fork:
https://github.com/belisarius222/meteor-eval-test
DISCLAIMER: this is code that allows anyone to run arbitrary code on the server. It's a proof of concept, not intended to be secure whatsoever.

Categories

Resources