How does Firebase.on() work? It's suppose to "Listen for data changes at a particular location", according to https://www.firebase.com/docs/web/api/query/on.html
,but how does the client know when to update itself? Is the client also a lightweight server that listens to the Firebase server or does the client automatically do an update every x seconds?
The Firebase client keeps a connection open to the server. Depending on where your app runs, this can either be a web socket or a so-called long-polling connection. Either of these ensures that the server can send new data to the client as soon as it is available.
The client listens for changes on the server and you need to update the client data (your objects) in the event callback.
As a suggestion, this can be greatly simplified with firesync.
Related
We are making a web application in Go with a MySQL database. Our users are allowed to only have one active client at a time. Much like Spotify allows you to only listen to music on one device at a time. To do this I made a map with as key the user ids and a reference to their active websocket connection as a value. Based on the websocket id that the client has to send in the header of the request we can identify weather the request comes from their active session.
My question is if it's a good practice to store data (in this case the map with the user ids and websockets) in a global space or is it better to store it in the database.
We don't expect to reach over 10000 simultaneously active clients. Average is probably gonna be around 1000.
If you only run one instance of the websocket server storing it in memory should be sufficient. Because if it for some reason goes down/restarts then all the connections will be lost and all the clients will have to create them again (and hence the list of connection will once again be populated by all the clients who want to use the service).
However, if you plan on scaling it horizontally so you have multiple websocket services behind a load balancer, then the connections may need to be stored in a database of some sort. And not because it necessarily needs to be more persistant but because you need to be able to check the request against all the services connections.
It is also possible to have a separate service which handles the incoming request and asks all the websocket services if any of them have the connection specified in the request. This could be done if you add a pub/sub queue and every websocket service subscribes to channels for all its websocket ids and the service that receives the request then publishes the websocket id, and the websocket services can then send back replies on a separate channel if they have that connection. You must decide how to handle if no one is responding (no websocket service has the websocket id). Either the channel does not exist, or you expect the answer within a specific time. Or you could publish the question on a general topic and expect all the websocket services to reply (yes or no).
And regarding whether you need to scale it I guess depends mostly on the underlying server you're running the service on. If I understand it correctly the websocket service will basically not do anything except from keeping track of its connections (you should add some ping pong to discover if connections are lost). Then your limitation should mainly be on how many file descriptors your system can handle at once. If that limit is much larger than your expected maximum number of users, then running only one server and storing everything in memory might be an OK solution!
Finally, if you're in the business of having a websocket open for all users, why not do all the "other" communication over that websocket connection instead of having them send HTTP requests with their websocket id? Perhaps HTTP fits better for your use case but could be something to think about :)
Angular has two ways data binding which is cool, so I just wonder if it could be sync in Server-Client binding? For example, usually we would request data by $http
$http.get(apiURL)
.then(function(rsp){
console.log('getRsp', rsp);
});
I hope it could send request automatically once server side (inside database for example) changes.
In tranditionally, we can use timeout, but it is kind old way, and watsting resource. What if we can listen the server change? But how?!
You can achiece this by using socket.io. Both on server and client side. By using timeout all of the clients will repeatedly keep on calling the server even if there is no update. With sockets you can keep a channel open between server and client. The server will only notify the client whenever there is a change in the data.
You can find a lot tutorials for sockets on the internet.
If my model data is changing how to refresh the site automatically to display the changed data?
Is this possible at the server or do I have to write some client code for this?
Thanks for helping.
Michael
You have to write client side code to do this, the server has no relationship with the client once its sent the response - the connection is closed, the server moves on to other requests.
You need to use Javascript to poll the server and update based on server side changes - you can use a data binding framework such as Knock Out, or a larger framework such as Angular to make this easier.
SignalR may help you here, in that its a system which plugs into both the client and server side, keeps open a connection so you can send data to the client side instantly from the server.
Let's say we have several clients connected to App Engine using Channel API. Each client sends messages, which should be propagated to other conntected clients according to some rules. The tricky part is that clients may not be to the same App Engine instance.
Is there any way to push data from one instance to the others?
(Yes, I know about Memcache, but this would require some kind of polling.)
You're asking two questions here.
a. Can you push data from one instance to another without the use of polling. The answer is generally no.
b. Can one client send messages to the server that can be propagated to other clients? Yes, and this does not require propagating messages to other server-side instances.
Consider the Channel API as a service. Clients are connected to the Channel API service; they are not connected to any particular instance. Therefore any instance can send messages to any client.
You'll need to store the Channel tokens of your clients in the datastore, in some way that's queryable to match your rules.
Your client makes an HTTP request to send a message to your server.
The handler on the server queries for channel tokens that it needs to propagate the message to (either from memcache or datastore).
The handler on the server sends messages to all the clients.
If the list of destination clients is extremely large, you might want to do steps 3/4 in a task queue where the operation can run longer.
It does not matter what instance a client is connected to, that's hidden from you by the API.
Clients can only "reply" to message via standard HTTP commands, they don't actually have any way to respond via the channel API directly.
So Client A on server A1 wants to sent a message to client B on server B1.
Client A posts to a handler. That might be instance A1 or B1. It does not matter which as the server now passes the message on to client B whatever server client B is connected to via the Channel API.
The real point is that no App Engine instance has any data at all, in general. So it does not matter which instance you connect to, it might be the 99th instance or the very first to start up. So you have to design your application so that it's irrelevant what instance is in use.
Client sends message to server via HTTP.
Server sends message to N clients via the channel API.
Channel API does not make a fixed frontend-instance-to-client connection. Any frontend instance can push message to channel if it knows the channel ID.
What you need to do is pass messages cross-channel.
User one sends message normally to server (e.g. via GET)
Server looks up channel ID of second user and pushes the message
Repeat procedure in other direction: second user to first user.
I am developing an application, i need date and time of the user who is accessing(ie Client's date time), how can i get it to server side........?
You can send the current time to server, everytime a client connects to the server. I am assuming you client is a web browser. In that case handle the document.onload event, and write a script that can send time to the server, each time the client loads a page.
If you have a different type of client, this would need to be handled differently.
You can get client time with javascript and send it to server.