How to store a file on the server?

I want a special snowflake server for christmas!

  • How do I implement my special snowflake server? When a client connects to the server, the server should send some pre-defined data. I'm thinking a pickled python list would be best here. The client would take this data, turn it back into a list, and store it. Occasionally, the client will send some instructions to the server. The server will take these instructions and apply them to a list. Once that is done, the server should push the new data to all clients listening. An example in case this is unclear: Alice's and Bob's clients both connect to the server and both receive "list = ([0,0,0])". Bob sends "add 1 to list[0]". The server has a subroutine for handling this; the server's internal list now looks like "list = ([1,0,0])". The server then pushes "list[0] = 1" to both Alice and Bob. Eve connects now and receives "list = ([1,0,0])", and so on. What do I use to do this? I've tried using the http://docs.python.org/library/socket.html but I honestly have no idea how I could make the server interact with multiple clients while maintaining a "master" list that any client can change. Threading seems promising, but eventually I would like a lot of clients and I've heard threading doesn't scale well. Maybe I could do this somehow over http with a cgi file and a database, but I don't know how I could push the changes. I've looked into WebSocket, but I can't find enough information about it and I still can't figure out how to handle multiple clients. I'm also having trouble getting the client to listen and get ready to send things at the same time. How would you do this? Are there any projects already out there that are made for this? Any links to tutorials or easy examples would be greatly appreciated, too. I would like to write both the client and the server in Python, but that's not set in stone. This would need to run on a unix box. Thanks for the help!

  • Answer:

    How would you do this? So your project needs a persistent store for list-type data, with multiple users connecting over the network? Why are you not using your favorite free database server for this, with clients polling for new data at regular intervals? A full database might be overkill for your solution, but the software required is free and the time it will take you to implement it properly is definitely less than what you would need to roll your own. Maybe I could do this somehow over http with a cgi file and a database, but I don't know how I could push the changes. An http server is not strictly required - your clients can connect to the db server directly using an appropriate python wrapper ( subject to network architecture/ security concerns ). If there is a lot of data, and you don't want to send the entire list over the network every time something changes, a simple way would be to add a timestamp field to each entry and only send data that has changed since the last update.

wayland at Ask.Metafilter.Com Visit the source

Was this solution helpful to you?

Other answers

Also, can you give us an idea of the scope of your project? Is it for work or a hobby project? How many users are you expecting? How often will the data change? How much data will be passed around? Is it mission critical? Are there security concerns? How much of a problem is it if some clients are left with stale data? Your description as given could apply equally well to a toy vending machine appliance for a university dorm and a full-blown corporate network handling financial transactions, the answers you get will be more useful if you tell us which one you are going for.

Dr Dracator

Ah, forgot to mention: I don't want the clients to be able to change the list directly. Instead, I want the requests by the clients to be handled by the server so I can have a set of rules. For example, say I don't want anyone to be able to add more than 3 to number. Also, I would like to eventually be able to serve different data based on who the client is (either by a username prompt or IP address). The list will get large and I'm expecting rapid successions of changes followed by slower ones, so it feels like having the client look for changes every x seconds or whatever would be a waste. Correct me if I'm misunderstanding something, though.

wayland

I'd do it in http://twistedmatrix.com/trac/, which has the right abstractions and good documentation/examples.

themel

If you're absolutely determined to do real push from server to client, you're going to want your clients to create connections that stay alive for as long as their sessions do (having your end open connections back to them when you want to push something is a configuration nightmare that you don't want to tangle with). Personally, I'd be inclined to offload the encryption and authorization you're going to need to ssh, using port forwarding; that would also mean that your server only needs to keep open one persistent TCP connection per client. Have a look into the format of an opensshd authorized_users file - you can lock stuff down pretty well.

flabdablet

Setting up a system wherein the clients do the active connecting every x seconds has two disadvantages: there is some lag time for updates to propagate (which implies the potential for conflicting updates), and it is not the most efficient plan in terms of computing resources. It is far and away the most efficient system in terms of how much time it will take you to set up. A client/server based system of this kind will have fairly high load capabilities; hundreds or thousands of clients connecting every 30 seconds is still a fairly light load for an apache server if it's only updating with changes. Doing it this way allows you to build it as a straightforward http request, with auth happening in any of a variety of ways. What's answering the request could be as simple as a php script (select changes from db since last update, send changes). If you really want to build it as a socket-based application, it sounds like you're going about it in the right way. It also sounds like you're combining two problems and getting confused about what solution solves which problem. You can think about the list update operations totally independently of the transport mechanism, and probably should. Regardless of what transport mechanism you're using, you need to build in something to make sure that updates from two different threads (or http requests, or thrown pigeons) don't step on each other.

contrarian

How fast does this need to happen? I mean if speed isn't too big of a concern, the easiest way to do this is just with HTTP polling. Clients send an http GET every second, and in some cases they do an http POST. You wouldn't even need to write the server, just use apache. so client code would just be something like this: while(true){   a = get("https://wherever/filename",username,password);   if(a != b){     handle_change(a);     b = a;   } } where get() takes a URL and a username/password and the server uses http basic auth. Now, if you need it to be more realtime, your server could still be pretty simple. Open a server socket and listen for new connections. When a new connection comes in, send a copy of the state to it. In Java you have a Separate objects for reading and writing to a socket (an input stream and output stream) For this application you would store the output streams in one collection and listen to the input streams on one thread for each of them. When new data comes in on the input stream, you would then update your internal model (for new connections) and then pass the information you revived from the client on to all the other clients (the data you receive and send back out can be the same, and the code to apply the changes can be the same on both as well. )

delmoi

This seems ideal for an actual database. You could write a few scripts to represent the client-side portion, and just send queries directly to the database over TCP. Usually this gets overlooked because databases so frequently get used with a web front-end, but connecting directly to them to execute queries is exactly what you're asking about.

odinsdream

People are offering all sorts of complex multi-tier solutions. Honestly, this problem sounds trivial to me. Use Twisted. Let clients connect. Periodically send out the serialized list to all connected sockets (don't use pickle, btw, it's not compatible between versions). If you receive data back, run it through your rules engine. Store the list both in a file and in memory... write through to disk on every update, and read from disk only on startup, otherwise work from memory.

Netzapper

Ewww. Think open and better accepted standards. You don't want to serialize to Python, use JSON so you at least have the hope of future web-app-ification. True push is almost impossible, that implies a service running on the client machine and the server being able to open a connection to the client on demand which isn't going to happen with all of the NAT in place on the network without a lot of firewall rules setup, crossing fingers, sacrificing chickens. If you really want to get close to that ideal, start with a chat server like solution (IRC/XMPP). Your server runs a chat server, with a room that's protected via auth. Th ere's plenty of IRC/XMPP client code out there that handles automatic reconnection. Then your app is another client that joins the same 'room' and listens for commands and 'says' data. Client: connect server 'the.app.com:666' auth 'user@password', join 'app_channel'. listen for 'data: *data here*' messages. do something with them. send 'app: add 1 1000' commands. receive 'data: *data here*' messages. repeat. Server: connect ... on_new_client: send 'data: *data here*' private message. listen for 'app: add *' messages. verify/check permissions/etc. do work. send 'data: *data here*' update. repeat. Presto. Stable well tested client-client message passing router. Server is just another client that responds to certain type of messages. Clients just listen for data messages and send modification commands. Any 'chat bot' code could easily be modified to do this. I would totally use XMPP vs. IRC because the relative ease of encapsulating data and extracting it from the XML message, and because the ejabberd XMPP server is so solid you could throw a brick at it and it wouldn't even flinch. In fact, the not the metafilter XMPP chat server mu.jklmnop.net has a per-user chatbot that tracks conversations with something as simple as: message => sub { my ($cl, $acc, $msg) = @_; my $repl = $msg->make_reply; $repl->add_body($RS->reply($msg->from, $msg->any_body)); $repl->send; }, All you would have to do is check $msg->any_body against your commands, $msg->from against your authorization code, put your data in $repl. Looks complicated, but like Netzapper says, it really isn't. I'm just breaking out the session/clients handling and letting a robust pre-existing chat server manage that. Then the clients and server become just a simple listen for messages and respond loop and all of the connect/reconnect stuff gets taken care of automagically.

zengargoyle

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.