I am making a webapp that has to be connected to an Arduino for its inputs so the contents of the webpage change.
I am currently not done yet, so I'm just trying it out with vars I have created and given random numbers. However, I am new to jQuery and cannot get it to work properly. For instance, I have the variable light = 100 and I want to make an if statement that if light > 100 the website displays the message: your plant is happy.
I don't know how to change the value with just the input of a variable, without having to click on any elements or anything.
I'm assuming that you are using Arduino hardware to detect the intensity of light and then use that information to update information on a webpage in real time.
One way to do this is:
Define the ranges for the plant state (eg. 'happy' 100+, 'okay' 80 to 100, 'sad' < 80, etc.)
Program your Arduino board to send the state to your server (eg: a python flask server) whenever the light intensity moves in and out of the set ranges.
Use Server Sent Events (SSE) or WebSockets to update the plant state into browser clients which are connected to your web server.
Related
Alrighty! I'm working on small chat add-on for my website, and when a user logs on they'll see the chat history, I'm using a Javascript Object to store all messages in my NodeJS server, now I'd like it so whenever more than fifty entries are in the Object it adds the latest message and removes the oldest, I'd like this to limit my server from handling a lot of messages every time a user logs on. How would I be doing this?
Here's how I store my messages,
var messages = {
"session":[
]
};
messages.session.push(
{
"name":user.name,
"message":safe_tags_replace(m.msg),
"image":user.avatar,
"user":user.steamid,
"rank":user.rank,
}
);
I could also just do loading the last fifty messages in the JSON Object but whenever I run my server for a long time without restarting it this Object will become extremly big, would this be a problem?
Since you are pushing elements to the end of your array, you could just use array shift() to remove the first element of the array if needed. e.g.
var MAX_MESSAGES = 50;
if (messages.session.length > MAX_MESSAGES) { messages.session.shift(); }
To answer the second part of your question:
The more data you hold, the more physical memory you consume on the client machine, obviously. Which can - by itself - be a problem, especially for mobile devices and on old hardware. Also; having huge arrays will impact performance on lookup, iteration, some insert operations and sorting.
Storing JSON objects that contain chat history in the server is not a good idea. For one you are taking up memory that will be held up for an indefinite period. If you have multiple clients all taking to each other, these objects will continue to grow are eventually impact performance. Secondly once the server is restarted, or after your clenan up these objects, the chat history is lost.
The ideal solution is to store message in a database; a simple solution is mongoDB. Whenever a user logs in to the app. Query the db for that users chat history (here you can define how far back you want to go) and send them an initial response contain this data. Then whenever a message is sent, insert that message into the table/collection for future reference. This way the server is only responsible for sending chat history during the initial signon. After that the client is responsible for maintaining any added new message.
I am currently developing a game using NodeJS + SocketIO but is having problem with the amount of data being sent. The server currently sends about 600-800 kbps which is not good at all.
Here are my classes:
Shape
Pentagon
Square
Triangle
Entity
Player
Bullet
Every frame (60 fps), I update each of the classes and each class will have an updatePack that will be sent to the client. The updatePack is pretty simple, it only containts the object's id and coords.
At first, I thought everyone's game are like that (silly me). I looked into several simple games like agar.io, slither.io, diep.io, and rainingchain.com and found that they use < 100 kbps which made me realize that I am sending too much data.
Then I looked into compressing the data being sent. But then I found out that data are automatically compressed when sending in Socket.io
Here is how I send my data:
for(var i in list_containing_all_of_my_sockets){
var socket = list_containing_all_of_my_sockets[i];
data = set_data_function();
socket.emit('some message', data);
}
How can I make it send less data? Is there something that I missed?
Opinionated answer, considering a way games handle server-client traffic. This is not the answer:
Rendering is a presentation concern. Your server, which is the single source of truth about the game state, should only care about changing and advertising the game state. 60fps rendering is not a server concern and therefore the server shouldn't be sending 60 updates per second for all moving objects (you might as well be better of just rendering the whole thing on the server and sending it over as a video stream).
The client should know about the game state and know how to render the changing game state at 60fps. The server should only send either state changes or events that change state to the client. In the latter case the client would know how to apply those events to change the state in tandem with the state known to the server.
For example, the server could be just sending the updated movement vectors (or even the acting forces) for each object and the client could be calculating the coordinates of each object based on their currently known movement vectors + the elapsed time.
Maybe its better not to send data every frame, but instead send it only on some particular events (etc. collisions,deaths,spawns)
Whenever a message is send over a network it not only contains the actual data you want to send but also a lot of additional data for routing, error prevention and other stuff.
Since you're sending all your data in individual messages, you'll create these additional information for every single one of them.
So instead you should gather all data you need to send, save it into one object and send this one in a single message.
You could use arrays instead of objects to cut down some size (by omitting the keys). It will be harder to use the data later, but... you've got to make compromises.
Also, by the looks of it, Socket.IO can compress data too, so you can utilize that.
As for updating, I've made a few games using Node.js and Socket.IO. The process is the following:
Player with socket id player1 sends his data (let's say coordinates {x:5, y:5})
Server receives the data and saves it in an object containing all players' data:
{
"player1": {x:5, y:5},
"player2": ...
...
}
Server sends that object to player1.
player1 receives the object and uses the data to visualize the other players.
Basically, a player receives data only after he has sent his own. This way, if his browser crashes, you don't bombard him with data. Otherwise, if you've sent 15 updates while the user's browser hanged, he needs more time to process these 15 updates. During that time, you send even more updates, so the browser needs even more time to process them. This snowballs into a disaster.
When a player receives data only after sending his own, you ensure that:
The sending player gets the other players' data immediately, meaning that he doesn't wait for the server's 60 times-per-second update.
If the player's browser crashes, he no longer sends data and therefore no longer receives it since he can't visualize it anyway.
Short question:
Can latency, when a client is sending packets to the server suddenly change a lot?
Long question(the problem I've got):
I'm making a html game using websockets and currently working on client side input prediction, I'm using the same code for client and for server to check for collisions, calculate new player positions, 30times/second. This is how I update player movement on both server and client side:
if(controls.pressingRight === true)
{
if(controls.dx < settings.MAX_X_SPEED)
{
controls.dx += settings.DELTA_X_SPEED;
}
else
{
controls.dx = settings.MAX_X_SPEED;
}
}
if(*noCollisions*)
{
game.me.x += controls.dx;
}
This way the player movement is kind of smooth. When a user press and holds down "D" keyboard button conrols.pressingRight value is changed to true, and it is true until player releases the "D" button. The reason I wrote my code is because I'm not sure if the problem is in my code or it has something to do with the change of latency. For example I click D button and quickly release it and my player on my client canvas moves like ~7pixels BUT on my server side player moves like 20pixels or more to the side(though sometimes both client and server side moves the same amount of pixels). I'm guessing that the problem is because when I press button down to move the player the latency might be low, let's say 20, but when I release the ping might be like 200 which means the packet was delivered later than it should've and because of that server still had my value of "pressingRight" as true. Am I missing on something?
Can latency, when a client is sending packets to the server suddenly change a lot?
Yes, absolutely. Connectivity changes occur all the time. This is especially true in mobile devices with antennas moving around quite a bit, causing momentarily loss in connectivity.
I'm making a html game using websockets and currently working on client side input prediction, I'm using the same code for client and for server to check for collisions, calculate new player positions, 30times/second.
...
When a user press and holds down "D" keyboard button conrols.pressingRight value is changed to true, and it is true until player releases the "D" button.
This is definitely one way, but if you go this route the server should be your source of truth as to the state of things. The client can move to where it think it moved, and then the server can update positions, bouncing the client back to the standard server-known version of events. In the optimal situation, the client won't move by much. However, lag happens, and sometimes that client is going to snap back to a location much further away.
There is no perfect solution to this problem when the game requires such interactivity. However, there are many ways to address it. See also: http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/
I'm trying to design a RESTful API to serve data to a front-end JS app, and in future a native mobile app once I get round to writing it.
I'm fairly new to front-end dev, so API designs are also fairly new to me. I'm writing a table tennis league app to start my learning, and one of the endpoints doesn't seem to quite fit with any example I've read of recommended API structures.
I have two entities, leagues and players. A league has a collection of players, and when a result is entered the players switch "position" in the league if the winner was below the loser before the match was entered.
A standard REST API might have endpoints as follows to update the details of a specific player within the league:
(POST/PATCH) - /api/v1/leagues/{league-id}/players/{player-id}
e.g. /api/v1/leagues/1/players/12
This is fine, but in my case, when a result is entered into the web app, 2 different players need their "position" value updating via the API. Ideally, I would have this set as a unique field in the database, so only 1 player can be at each position within the league at any given time. However, if that were the case, using an API endpoint as above, my front-end app would need to calculate the new positions of the players based on the entered result, update player 1, and then if successful update player 2 (rolling back on failure). Following this structure, the position field cannot be made unique, as following the update of player 1, they both have the same position value until player 2 is updated.
The only other solution that I can think of is to have some other appropriately named endpoint that takes a "result" object, does the logic of working out the players new position on the server side, updates accordingly, and returns some data for the UI to re-bind and update to.
So my question is this: which of the 2 methods outlined above would you choose, and why?
If you choose the latter, what data would you return from the API call for the UI to bind to? A full league of player data? Or just the two players that have been updated?
Thanks
I think I see two problems
you haven't defined enough resources
you are confusing http with your domain model
Try something like this
PUT /api/v1/matches/{match-id}
{ winner : { id }, loser : { id }, ... }
Put to the API a message describing the outcome of the game (POST is acceptable, PUT is better for idempotency).
As a side effect of this message's arrival, incorporate the results into your domain model. It's your domain model that should include the rules that describe how the rankings of players change when a game is finished.
When somebody wants to see the rankings of the players...
GET /api/v1/leagues/{league-id}/standings
you send them to a resource that returns a representation of the current rankings in your model.
The spelling of the uri doesn't particularly matter; I prefer "standings" because I believe that's a real thing in your domain. But if you wanted to reflect the data structure of your resources without additional context, you might use a spelling like
GET /api/v1/leagues/{league-id}/players?orderBy=position
The data representation in the body of the request sent to you by the client isn't a serialization of an entity in your domain model, it's a serialization of a message addressed to your domain model.
The choice of where to calculate the positions within the league is really subjective - I would suggest doing it at the server, since it involves searching the database again (other players' scores).
Since you have multiple players and you may update 2 players at a time, it would be better to send the players' scores in the request body with their positions, and return the calculated full league information in the response for each request, because that would simplify your client code and ensure that you get the latest data.
This suggestion is based on the assumption that you do not have large number of players in a league (may be > 100). In that case, I would suggest approach 1 is better.
So your API URL can be..
(POST) /api/v1/leagues/{league-id}
And your request body, can be
"players":[
{"player-id":"101", "newScore":"10"},
{"player-id":"103","newScore":"20"}
]
Your response can be the full list of players in the resulting league.
"players":[
{"player-id":"101", "position":"1"},
{"player-id":"102", "position":"2"},
{"player-id":"103","position":"3"}
{"player-id":"104","position":"4"}
{"player-id":"105","position":"5"}
]
I'm implementing presence with pubnub, and I'm encountering a problem, I create a method to get the presence in python, and its working properly, when I connect one to 20 users simultaniously, but once I created more, I didn't get the proper response of the joins users.. I created a simple js script to subscribe users..
var pubnub =[];
for(i=0; i<=100;i++) {
pubnub[i] = PUBNUB.init({
subscribe_key: "subkey",
uuid: "user"+i
});
}
After the first 20 I just get the occupancy in the response of the presence method, instead of the usual, join or leave action with the corresponding uuid.
Does it have a limitation, or perhaps, pubnub know that I'm opening them from the same ip and its blocking subscriptions somehow? I would like to know how it is the behaviour.
#cri_sys, this is a server-side optimization to be sure we don't flood you with data when there is too much presence data coming over the line.
Contact us at support#pubnub.com, and we can adjust it to < 20 behavior for you, or go into more detail on why you may want the alternative behavior when > 20.
geremy
The Presence Announce Max property is now exposed as a property in the Presence add-on panel in your account portal. You can set the value as high as 100. If you want it set higher, you need to contact support#pubnub.com.