I'm running a NodeJS server which is sending notifications to the clients when somebody does something, for example, when a client deletes a row from a grid, Socket.io informs the rest of the clients that a row got deleted.
In that example, I could add something like actionType: rowdeleted to the socket.io message and then just detect the actionType on the client side and refresh the grid. Anyways, the problem is that there can be infinite number of actions (and new ones can be added), so I can't code a function for each action type on the client side.
Then I thought maybe I can send some code via socket.io and make the client run it, but I'm not sure if that is the best way for doing what I want. Also, how are the clients going to run that code? Via eval?
I'm open to any suggestion :)
Have you considered something similar, but not as eval. You clearly must have the code to execute somewhere, be it on the server side. Why not create a way to let the client know what script/code/action to get and execute it.
I have used something similar out of a similar need. The action type referenced a script in a specific path on my server (/js/actions/ACTION.js). Upon getting the command to run the action, the client would check if it has the action, if not, it would go get the action. After that it would run the action on the script. RequireJS is good for this kind of thing. It will keep track of what actions you have and what actions you don't have. It will also make sure to get the action if it doesn't have it before it run some function that needs it.
eval is evil (c)
so I can't code a function for each action type on the client side.
there's no point emiting events from server if they wont be handled on the client(s)
have a client handle funcion for each type of event your server is emiting.
Otherwise bind on all events and handle then
Related
OK, the tite seems a little confusing, so I'll try to explain more thoroughly...
The process the page does currently follows the following sequence:
- User clicks a button
- server-side code goes retrieve data from the DB and exposes said data to the client using, populating, let's say, hidden fields.
- client-side code uses this data to fire up a an ActiveX component which performs a few tasks with the data provided.
And this works fine, however, we need to optimize the process because the ActiveX component is not fit to handle high volumes of data. We need to send data into "blocks" to the component, rather them send all data at once as it is done today.
However, I just hit a roadblock here, on how can I make the page go back and forth from server to client code multiple times? Like... "user clicks a button, server retrieves first block of data, sends to client, client executes ActiveX for the first block, client requests next block, server retrieves second block, sends to client, client executes ActiveX for the second block, client requests third block... and so on"? I can't get past the first request, since I can't register a client script block 2 times and expect AJAX to handle those multiple sequential callbacks...
Or is there a way?
This sounds more like an architectural issue than anything else.
What you should be doing here is:
1) User clicks a button. This is NOT a regular submit button. Just a plain old button that executes some local javascript.
2) Local javascript makes an AJAX request to determine how many records are available.
3) That javascript then does a loop based on the number of available records divided by the amount you want to pull per chunk.
3.a) Execute AJAX request for a chunk
3.b) Throw the data into your ActiveX control - which, btw, I really would suggest you guys think about getting rid of. There are so many issues with ActiveX that it's not even funny.
4) Repeat 3.a and 3.b until completion.
You'll notice that at no point was a full post back performed. You'll also notice that you shouldn't have to register any client script blocks.
Now the draw back here is purely in the ActiveX control. Can it be instantiated from javascript multiple times in a page or are you forced to only use a single instance?
If it's limited to a single instance, then you'll need a different approach entirely.
I have an ASP.NET page where a request is made and after a while server returns either new page or just file for download. I want to indicate on screen s that server is "Processing..." while it takes time before returning data.
To call javascript when user hits submit is easy. Also reload of page on Postback causes any "Processing..." indicators (some DIVs popping up at the top of page) to go away.
My problem is mostly cases when data returned by server is not a page but a file to store. How can I catch the moment that server started to return data, and run a javascript/remove "Processing" DIV ? Is it even a way to do so in case of reply of different mime type?
In which cases it is even possible?
There are a couple of ways to approximate what you're trying to do with timers and assumptions about what happened, but to really do what you're describing, you need to be polling the server for an indication that the download occurred.
What I would do is take the file, Response.WriteFile it, and then write a flag to some store, either a db, or the file system, or whatever, that uniquely identifies that the transaction has completed. On the client side, your script is polling the server, and on the server, the poll response is checking the store for the flag indicating that the download has occurred.
The key here is that you have to take finer control of the download process itself...merely redirecting to the file is not going to give you the control you need. If you need more specifics on how to accomplish any of these steps, let me know.
I just realized while testing an onClick function with firebug that it would be really easy for a user to change the value of the arguments being passed. This could mess thins up.
Is there any easy way to prevent this, especially when arguments need to be passed?
It is impossible. The code is executing on the user's computer. They are in control.
If they edit it and "mess it up", then that is on their head.
If they edit it and it submits an HTTP request to your server, and your server allows (for instance) that request to delete data belonging to another user then the problem is that your server didn't check that the user submitting the request had permission to delete that data before following through.
You cannot trust anything sent from the client. The user might hand-edit the URL arguments, or a script kiddie could send you a request not even using a browser at all. You must validate everything server-side.
No, this simply can't be done.
Once the script is loaded to the client's machine. He can use/modify it, as he wants.
I'd recommend validating the arguments against expected set of values, and/or business rules wherever the results are being processed (client/server). Ideally validation checks happen on the server where the user has no control. Validation on the client side could even be modified to allow invalid data entry.
There is no way to completely control it - only validate it based on criteria.
You can't prevent this action because JavaScript is a client side . Also you can never trust the client .
You should make a validation for any request at server side to protect your data against client misuse .
you can somehow make it hidden from client eyes
by using .delegate()
EX.
$("table").delegate( "td","click", function() {<br>
// write here your function<br>
});
The client can execute this script but it isn't direct in front of his eyes ..
Is it possible to directly bind server side events to client side objects in meteor?
I would like to update a view for example when a server side event triggers. On the other hand I'd like to fire a server side method when a user clicks a view item.
I could use Meteor#methods for all the events but that seems odd.
Or can I specify an eventhandler for example using EventEmitter outside the client- and server-scope so that it is available on both sides and trigger/bind events ob that very object?
Some confused about that I am thankful for hints into the right direction.
Regards
Felix
Update:
Using Meteor#methods works great in case user events should be mapped to server side actions. The other way around is still unclear. Asynchronous actions on serverside could persist their results in a collection which is pub/sub'ed to the client, which in turn could update some view due to the reactive context. But thats odd, cause persisting that kind of info is slow, wasted space and time. Any suggestions?
I believe you can use the Collection.observe on the server side to 'observe' events on the Collection as clients are inserting, updating, removing, etc... That might be a start if you are focused on Collections alone. I used it like a sort of server side event loop to watch for collection changes.
When a user clicks on something in a view try binding a Template Event to the View css selector and then calling a Meteor method which will notify the server of the event. See the examples of binding a key handler and/or button handlers to a Template.entry.event which then call a Meteor method notifying the server that something happened.
What about storing the progress in Session? You could do something like this:
Template.progress.value = function() {
return Session.get('progress');
}
Then, whenever you update the Session on the server, the client template will automatically get those changes.
Out of curiosity, how exactly are you performing asynchronous actions on the server? I'm still trying to figure that out.
i am using gwt.
i need to check some input data.
all checking functions are located in PHP server check.php
i am not using javascript checking executed from locally.
all i am doing is to send user input to server by ajax and validate in that place
and error message comes from server to client's gwt widget.
is it best approach??
i can do all checking from locally.but not doing.because server side is importent.
all checks must be resides in server so i am doing all checking from server.
if i do check locally and serverside two times ,then will it be best approach??
What you'll want to do is:
Use this account the next time you come back, or any of the others you've created, instead of creating an account each time you come to the site. Avoid this mess.
Create a .php page that accepts JSON-encoded data that you'd like to verify, and respond with some text like "OK" if it's valid. (I'm no PHP expert, but I'm sure there are plenty of them here)
Use GWT's RequestBuilder to send this data to the .php page, and call the RequestCallback's Response's getText() method. Check if the text is "OK" -- if so, the result is valid!
If you need more detail on any of the specifics, just let me know and I'll edit to clear things up.
Generally I agree with Jason (especially the with the first point :D).
I'd like to add that you should do validation on the client side first. Why? Because it allows you to weed out some obviously wrong inputs => less load on the server. But never accept the values from the client, just because your JS code said so - the general rule is to never trust the client side (because, well, it's the client side and the client can change the way your code works).
So in summary, I usually take these steps in my apps, they offer security and lower the load on your server, but may require a bit more work to write and maintain (especially if your client side and server side use different languages):
Validate input client side. If it doesn't pass, don't bother sending it to the server, just show an appropriate message.
If it does pass, send it to the server, but you must rerun the validation on the server side too.
If the server side validations report an error, send it back in some form (JSON with the error message and/or error code, set a HTTP response code, etc).