I have created an asp.net website. On that website the user can create webpages and put buttons. These buttons sends commands via web socket to a tray application I implemented. The tray application then takes the commands and passes them along to various third-party applications using TCP connections. the third-party applications then perform the commands and send back their status to the tray application. The tray application writes the status into an sql database. The website reads the status from the database and processes the status (for example, it highlights the button that send the original command)
Right now it is a mess. For example the third-party applications all handle the communication in different ways. How would I best go about organizing such an application?
I use ab sql database in between because I cannot be sure that the user wont reload the website. And then what happens to the web socket? Also, it can update its buttons on its own pace. Is that a good solution?
Also, my knowledge of TCP and socket programming is sorely lacking. Most resources, tutorials, guides just give really simple examples. Isn't there something better out there? (books, articles)
I am using a TCPListener that accepts the website requests in an infinite loop:
static void TcpListenerWorker_DoWork(object sender, DoWorkEventArgs e)
{
server = new TcpListener(IPAddress.Parse(Properties.Settings.Default.TrayAppServer), Properties.Settings.Default.TrayAppPort);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
while (true)
{
if (TcpListenerWorker.CancellationPending)
break;
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
...
Is there a better way to link the tray application to the website?
The tray application also has to check if the third-party application is running. Only if it is running, should the socket be created. If the third-party application crashes to connection is gone. How do I reestablish the connection properly?
The user should now if he can send commands. For that I check if the application is running like so
Process.GetProcessesByName("exApp1");
Is there a better way to check for the applications? Maybe by trying to establish a tcp connection and if it fails, the app is not running. But relying on a failed connection attempt might not be good decision.
A lot of errors occur. Connections disappear, commands do not arrive. Are there APIs I could use to handle these things better (better error and exception handling)?
Sorry, if all that sounds confusing. The entire project is a mess. Please tell me if I should explain more.
One thing I would do is sit back and unravel the spaghetti in your mind first. The fact ech uses a different means of communication should not matter if you have properly abstracted them.
The first question is "Do you need TCP socket level communication?" I see nothing that screams "yes" here. Assuming you do, your first issue is getting the socket communication. Get that up and running first. If this is multiple clients, there are open source projects you can start with to handle the communication bits. As an example, there is a project called Socket Server on CodePlex that can manage the sockets. I am, personally, not fond of the way the project is set up, but follow the documentation and get a server up. Or search for another piece that can do this for you.
Your next problem is "should I set up a socket?". If I am right, this sounds like a client side issue; if so, solve it separate from the socket connection and be done with it. I don't have bandwidth to determine if your method is the best here, but encapsulate that code and you can swap out the method of determining if the app is running later.
Now let's jump down to multiple apps communicate differently. If you have one in to multiple outs, think about a simplified service bus and then write adapters for the applications that need to listen. If it is multiple in to one out, then you need to write an adapter for the application anyway. Perhaps some apps do require socket level communication, and you need a socket to web API adapter (just an example, as I don't have enough detail).
The core of the advice is break the problem down and see what you can separate out and focus on. Many simple problems are generally easier to solve than one big complex problem.
Related
I'm facing an issue in a High Available Windows Services I developed with a master/slave setup.
Context:
The services itself synchronize data to two endpoints. One endpoint is synced to a local database, and one is an external. The database that is local is duplicated on both machines, so both master and slave need to sync this. The external endpoint only needs to be synced once.
The Master will by default sync to the external service, the slave will take over when the master is down. When the master goes back up and the slave is still synchronizing to the external, master will ask slave to finish a portion of the work, and then tell the master is done so he can continue the remaining work.
All this needs to happen asynchronously, I do not want the program to stop and wait for the other to respond (like the slave still handling the data).
I already implemented all the logic for this.
Setup:
Two Windows services running on two different machines.
Currently the communication is done over Named Pipes.
The problem:
Named pipes isn't reliable enough for the throughput that is being done. It also often crashes, and isn't made for reconnecting/closing and reopening a lot of times. I also face the problem that it just 'hangs' a lot when sending/receiving messages. Retrying sometimes works but I think I shouldn't be retrying. I need to have a reliable communication between the two instances.
Solutions:
I've been looking for an alternative to Named Pipes, but can't seem to find a solution of which I'm convinced that would work. Mostly because a lot of the technologies are for communication between a service and a client over http.
WCF over MSMQ is also not what I need, because I only want communication to happen when both are online. WCF in general is also more focused on one endpoint receiving data and sending a response. I need bidirectional communication, so both instances need to be able to receive and send messages at any time.
I think my best option is SignalR, but I'm also not convinced.
Have you looked at MassTransit over RabbitMQ?
We have been using them together very successfully both for intra-service and client/service communication for a few years now.
I am writing a chat program between a server and a client in C# .Net. Both users, aside from chatting can engage in different activities like remote desktop and playing games together.
I have a few questions:
Multiple threads will be sending and receiving stuff from the client at the same time, that means every option need to identify which packet is meant for him and take data from it ? (Running a remote desktop while transferring a file a same time, the remote desktop thread will see the file packets arriving at stream but should ignore it, right?)
What's a good buffer size to set for the socket I will accept clients in?
Do I communicate in form of specialized class containing the data or try to keep the communication as a byte array I send over the stream?
The questions 2 and 3 are impossible for us to answer because we don't know what the communication and the requirements look like.
As for handling multiple threads: that is hard to get right, I'd use an existing solution.
I suggest you have a look at 0MQ as it might prevent you from reinventing the wheel.
There are .NET client libraries available: http://nzmq.codeplex.com/ and a nuget package http://www.nuget.org/packages/clrzmq/2.2.5 as well.
A good start is The Guide
For a quick example see this C# server and its hello world client in C#
I am currently new to C# and I need to understand simple server-client architecture!
I am currently trying to write a simple server/client program where basically a client can send a variable to a server and the server can send it to another client. Problem is that I am really blind to this as I am still very new to C# although I have some experience with Java (But still not with networking).
My question is:
How many files will i Have to write?
Can anybody be nice enough to provide me with a framework or example for a program like this?
What is a TCP server?
This is intended to be for an online game. One client will roll the dice and the server must show all the other clients that this is the value the first client rolled.
Any help would be greatly appreciated!
Answer to all of your questions: MSDN - Network Programming (.NET 4)
Since you are planning on TCP (because you want state) you need to develop a strategy. You'll get plenty of information about establishing a connection and moving some sort of data back and forth. Google will give you more than you can handle. Without doing all the work, here are a few steps to get you oriented.
1) Connection Registration - When a client comes online and wants to communicate with the server it first needs to say "Hey I'm here and want to role some dice." This initial handshake could be a connection id that is used for a heart beat and/or transactions. The server will use this to identify data and the respective thread if open.
2) Heart Beat - Now that the client has registered with the server the client is responsible for providing a heart beat saying it's still there and still planning to continue work. Typically every 3 - 10 seconds is good.
3) Develop the Request/Response protocol - For "every command" there will be a formal process. This formal process will include the connection id but also a request id. The client will not accept a response unless it receives the corresponding request id. Furthermore, every request will require a success or fail response to identify if it conforms to the API or what not. Within the request will be the command or action to perform. Some people use int's to dispatch a command id then use a switch on the id to call an entry-point method (cmd id = 1 is connect(), cmd id = 2 is rolldice(), etc). You might include additional payload that identifies the result from the command.
In short, 1 is the handshake, 2 is the keep-alive and 3 is passing data back and forth.
Now whether to use socket or WCF, I'd recommend to have a basic understanding of TcpClient programming then run with WCF. You'll be amazed how simple socket programming is but the overhead is a killer. Nothing to be intimidated by. It's a lot of work to coordinate calls, threads and not to mention security. WCF on the other hand does shave some of this overhead off.
I'd check out this question...
How to use socket based client with WCF (net.tcp) service?
1) The number of files will depend on your particular implementation. You can create this architecture as simply as 1 class for the server and 1 class for the client (you can have more than one class in a file). Depending on the complexity and choices you make during the design you could have many files or just a few.
2) A good tutorial for a simple TCP server / client can be found here
3) A TCP server is a process that waits for a connection from a TCP client. TCP stands for Transmission Control Protocol. From Wikipedia: TCP provides reliable, ordered delivery of a stream of bytes from a program on one computer to another program on another computer.
Users in field with PDA's will generate messages and send to the server; users at the server end will generate messages which need to be sent to the PDA.
Messages are between the app and server code; not 100% user entered data. Ie, we'll capture some data in a form, add GPS location, time date and such and send that to the server.
Server may send us messages like updates to database records used in the PDA app, messages for the user etc.
For messages from the PDA to server, that's easy. PDA initiates call to server and passes data. Presently using web services at the server end and "add new web reference" and associated code on the PDA.
I'm coming unstuck trying to get messages from the the server to the PDA in a timely fashion. In some instances receiving the message quickly is important.
If the server had a message for a particular PDA, it would be great for the PDA to receive that within a few seconds of it being available. So polling once a minute is out; polling once a second will generate a lot of traffic and, maybe draim the PDA battery some ?
This post is the same question as mine and suggests http long polling:
Windows Mobile 6.0/6.5 - Push Notification
I've looked into WCF callbacks and they appear to be exactly what I want however, unavailable for compact framework.
This next post isn't for CF but raises issues of service availability:
To poll or not to poll (in a web services context)
In my context i'll have 500-700 devices wanting to communicate with a small number of web services (between 2-5).
That's a lot of long poll requests to keep open.
Is sockets the way to go ? Again that's a lot of connections.
I've also read about methods using exchange or gmail; i'm really hesitant to go down those paths.
Most of the posts i've found here and in google are a few years old; something may have come up since then ?
What's the best way to handle 500-700 PDA CF devices wanting near-instant communication from a server, whilst maintaing battery life ? Tall request i'm sure.
Socket communication seems like the easiest approach. You say you're using webservices for client-server comms, and that is essentially done behind the scenes by the server (webservice) opening a socket and listening for packets arriving, then responding to those packets.
You want to take the same approach in reverse, so each client opens a socket on its machine and waits for traffic to arrive. The client will basically need to poll its own socket (which doesnt incur any network traffic). Client will also need to communicate its ip address and socket to the server so that when the server needs to communicate back to the client it has a means of reaching it. The server will then use socket based comms (as opposed to webservices) to send messages out as required. Server can just open a socket, send message, then close socket again. No need to have lots of permanently open sockets.
There are potential catches though if the client is roaming around and hopping between networks. If this is the case then its likely that the ip address will be changing (and client will need to open a new socket and pass the new ip address/socket info to the server). It also increases the chances that the server will fail to communicate with the client.
Sounds like an interesting project. Good luck!
Ages ago, the CF team built an application called the "Lunch Launcher" which was based on WCF store-and-forward messaging. David Kline did a nice series on it (here the last one, which has a TOC for all earlier articles).
There's an on-demand Webcast on MSDN given by Jim Wilson that gives an outline of store-and-forward and the code from that webcast is available here.
This might do what you want, though it got some dependencies (e.g. Exchange) and some inherent limitations (e.g. no built-in delivery confirmation).
Ok, further looking and I may be closer to what I want; which I think i a form of http long poll anyway.
This article here - http://www.codeproject.com/KB/IP/socketsincsharp.aspx - shows how to have a listener on a socket. So I do this on the server side.
Client side then opens a socket to the server at this port; sends it's device ID.
Server code first checks to see if there is a response for that device. If there is, it responds.
If not, it either polls itself or subscribes to some event; then returns when it's got data.
I could put in place time out code on the server side if needed.
Blocking on the client end i'm not worried about because it's a background thread and no data is the same as blocking at the app level; as to CPU & batter life, not sure.
I know what i've written is fairly broad, but is this a strategy worth exploring ?
I have a client-server app where the client is on a Windows Mobile 6 device, written in C++ and the server is on full Windows and written in C#.
Originally, I only needed it to send messages from the client to the server, with the server only ever sending back an acknowledgement that it received the message. Now, I would like to update it so that the server can actually send a message to the client to request data. As I currently have it set up so the client is only in receive mode after it sends data to the server, this doesn't allow for the server to send a request at any time. I would have to wait for client data. My first thought would be to create another thread on the client with a separate open socket, listening for server requests...just like the server already has in respect the client. Is there a way, within the same thread and using the same socket, to all the server to send requests at any time?
Can you use something to the effect of WaitForMultipleObjects() and pass it a receive buffer and an event that tells it there is data to be sent?
When I needed to write an application with a client-server model where the clients could leave and enter whenever they want, (I assume that's also the case for your application as you use mobile devices) I made sure that the clients send an online message to the server, indicating they were connected and ready to do whatever they needed doing.
at that time the server could send messages back to the client trough the same open connection.
Also, but I don't know if that is applicable for you, I had some sort of heartbeat the clients sent to the server, letting it know it was still online. That way the server knows when a client was forcibly disconnected from the network and it could mark that client back as offline.
Using asynchronous communication is totally possible in single thread!
There is a common design pattern in network software development called the reactor pattern (look at this book). Some well known network library provides an implementation of this pattern (look at ACE).
Briefly, the reactor is an object, you register all your sockets inside, and you wait for something. If something happened (new data arrived, connection close...) the reactor will notify you. And of course, you can use only one socket to send and received data asynchronously.
I'm not clear on whether or not you're wanting to add the asynchronous bits to the server in C# or the client in C++.
If you're talking about doing this in C++, desktop Windows platforms can do socket I/O asynchronously through the API's that use overlapped I/O. For sockets, WSASend, WSARecv both allow async I/O (read the documentation on their LPOVERLAPPED parameters, which you can populate with events that get set when the I/O completes).
I don't know if Windows Mobile platforms support these functions, so you might have to do some additional digging.
Check out asio. It is a cross compatable c++ library for asyncronous IO. I am not sure if this would be useful for the server ( I have never tried to link a standard c++ DLL to a c# project) but for the client it would be useful.
We use it with our application, and it solved most of our IO concurrency problems.