views:

76

answers:

4

Hello I am making a proof of concept-application that maybe one day will be a source of income.
The data-flows dictates that have to be a client - server app, information is shared between clients and should be persisted.

I have experience of writing stand-alone apps, I have modelled the app and have written the client. The communication with the server is only a stub.

So now I have a protocol in form of an (C#) interface with method calls.
Four of the calls is for requesting information and two for pushing data to server.
The data is in classes that I would like to freeze-dry and revive on the other side.

In the future I would like to port the client to other OS'es so I wouldn't like to do something that I have to rewrite the server from cratch, if I can't avoid that.

I would also like to update the data in the client at undetermined intervals. Today I don't know how to do that.
My application is single-threaded, Windows Forms

My assumptions is that:
* I will use TCP/IP in some form below everything. I have to set up the channel, set IP adresses and stuff like that, I have an idea what I have to do.
* The front-end of the server will be multi-threaded to allow for more that one client to talk with the server at the same time. The syncronising will be internal to the server.
* Projected amount of data, maximum: Text 1000 * 1kbyte, 100 000 objects with 4 states. 20 000 updates/day. But that is way in the future.

May three biggest question is
1. Communication protocol. How do I map my method calls, the ones I have in the interface to something that I can transmit on a TCP/IP channel?
2. I need advice on a good pattern to serialize the reading and writing into the "data base", data base doesn't need to be a sql server.
3. Can I allow the server to send updates to the client without making it a multi-threaded app with one thread only listening to the socket?

I will happily update my question if more information is needed.
Thanks in advance.
Gorgen

A: 

SOunds like a good candidate fror .Net remoting.

This will abstract away a lot of the low level byte shifting, and allow you to write comms code in domain level language.

Visage
.NET remoting is deprecated. You likely should use WCF for new projects.
nos
A: 

1) Please elaborate on this question a little bit. I don't fully understand what exactly you want explained here.

2) I'm not sure what you mean by this (don't know anything about patterns in the programming sense) but would it not be wiser to read and write asynchronously so that you only access the database when you have something to read/write

3)Yes this is doable but you really should create another thread to update your clients. This is advisable for a few reasons, but mainly you want to compartmentalise your program logic as much as possible to allow you to isolate problems within your software a lot more easily.

Dark Star1
A: 

From the sounds of it, WCF is right up your alley. Although it can be a little complex at first glance once you start digging into it things are fairly straightforward. This way you let the framework handle asynchronous calls and wiring up the network side of it.

As far as the server sending updates to the client, you'll want to look at a duplexed binding in WCF and on the server side maintaining the list of known (connected) clients. Of course wrap any calls back to the client in try-catch blocks since you never know when a hiccup will occur and the client is suddenly inaccessible.

Agent_9191
I have started to look at WCF (Windows Communication Fundation). I suppose if I choose this way I will be tied to .NET and I can't delevop for other OS'es. Is it so?Also, WCF, will it solve my question 2 and 3 too?
Gorgen
Since you tagged the question as .NET I assumed that's the direction you were looking for. But yes, if you choose WCF you're tied to .NET on the server. Depending on the bindings you choose you may be able to have non-.NET clients.Depending on the binding you choose (which would need to be a duplex-binding, and thus easiest to achieve with a .NET client), WCF is a viable answer to #3. As for #2, I'm not sure what you're expecting to be different from stand-alone apps with a database back-end.
Agent_9191
Thank you for clarifying, I just wanted to get a feel of the flexibility of the solution and I have to say that I have somewhat conflicting goals, get something working and to make it future-proof. #2 If I service a client and another client wants to be served, I have to start a new thread or reject the second client, maybe put it on a waiting list. Then I have two threads potentially wanting to write to the same data and the need for some lock or anything. Maybe it happens behind the curtains with WCF but somewhere it has to be done.
Gorgen
As far as the threading issue of multiple clients, WCF handles that under the hood for you. As far as accessing/writing the same data from multiple clients, you'll want to research further on "optimistic concurrency" and "pessimistic concurrency" in terms of locking data. My usual approach on the topic is optimistic concurrency with great audit capabilities, but it really depends on the demand of the project. Some ORM-layer frameworks (like Entity Framework) can handle that for you as well.
Agent_9191
Ok, I will check that. When I have got WCF to work....
Gorgen
A: 

I just wanted to add some flesh to Agent_9191's answer and record the steps I took for the posterity :

Question 1

  • Read Getting started tutorial carefully (no I didn't but I wished I did)

  • Changed the example to my fit my own interface

  • The default generated proxy changes the interface quite substancially; All collection classes is made to array and all classes that you want to transfer is stripped of all methods, due to the delivery mechanism. To access the domain classes both in server and client follow the advice of this post

  • The domain classes that will be used have to be serializable with [DataContract] and [DataMember] from System.Runtime.Serializion.dll

  • These WCF samples helped me to understand what's going on too

Question 2

  • Made a class that implemented my interface again
  • added an static instance in the Service
    private static MyManager myManager = new MyManager();

  • simply forwarded all the calls
    public Project[] GetProjects() { return myManager.GetProjects(); }

Question 3

Two-way contract: How to: Create a Duplex Contract

I will have the state in memory and not in a database for now, when I change that I will rethink the approach.

Gorgen