C# local network discovery of own agents - c#

I have this piece of software, let's call it an agent, deployed on every machine in a local network. Every once in a while, it needs to pull an update from the server.
That means, each machine in that network connects to my server and downloads the new version which is a few MB.
What i want to achieve:
Once the first machine pulls the update from the server, the other machines should get the update from the one(s) that already got it, in a peer network.
The ideas i have so far:
Use a shared folder in the network, first machine that gets the
update places it into that shared folder. Every machine checks the
shared folder first before going to my server. This works, but i get
problems if sharing is not enabled in windows, firewalls, access
rights, etc.
Each agent opens a socket available to the internal network (probably open a tcp socket on 127.0.0.1 on a random port that all
the agents know about). Before pulling the update, broadcast to the
network that you request an update, and if nobody replies that they
have the update, proceed to the server. Else, get the update from
the agent who replied, since they probably already got the update
from the server or from some other agents. The problems i have here
is that i don't really know how to proceed with the network
discovery, nor the performance impact this could have.
Build a local server app, publish it on some node of the internal network (one of the computers) that all the other agents connect to
for updates. This local server gets the update only the first time,
and it "caches" it, giving it to any agent requesting it. This is my
least favorite option, since it implies a local server. If that one
fails, no other node can get updates. Of course, i can implement
fallback mechanism to go to the real server, but still. And also,
every agent will need to know exactly who the "master" is, and that
would be even harder to manage.
If you guys have any better ideas, or any guides to lead me to, would be much appreciated.
Thank you.

Essentially you
either have to maintain a list of the computers that already have the update and pick one randomly to acquire the update,
or have a broadcast query that all computer with the update respond and pick one.
I would go with the broadcast in the spirit of peer-to-peer.

Related

C# Identify Network Connected To

I'm working on an app that will copy files to a server.
I need a way to determine if the client is physically attached to the network (LAN cable or wirelessly attached), or if the client is connecting via some other way.
For example, if my app was running on my laptop at the office I might be plugged in. Later I disconnect and go home and my laptop is then connected to my router and my provider.
I thought of checking the domain name but that just gives me the name of my dev PC. I also considered seeing if a file share is available, but if someone who was NOT really connected created a mapping with the same name then its a false result.
In the end the app will determine how it's connected, and then either do a file copy or FTP the file in.
How can I tell how it's really connected?
Thanks

Push notifications to active directory groups even if offline

I have a WPF applications that runs on 2'000 PCs (xp, vista, win 7, win 8),
and the only thing it does is to show new notifications taken from a main server.
At the moment everything works trough pooling and it is hard for the server to handle that load.
I'm now required to provide the same service to another customer which has 4'000 PC,
so pooling is no longer an option.
The customer wants also to be able to specify which Active Directory group should receive the notification,
and every notification must been received by the client even if offline at the time (it will receive it when back online).
Security is not an issue.
I'm searching for the best architecture suited for the task,
this is what I have considered so far:
1) WCF-MSMQ: discarded, it requires msmq active on every client machine.
2) WCF-nettcpbinding publish-subscribe (https://msdn.microsoft.com/en-us/library/ms752254(v=vs.110).aspx):
It would be perfect but how I'm supposed to handle different groups?
Should I check the group of the user and based on that subscribe it to a different topic?
3) Keep all clients always connected to the server:
on connect the client sends it's Domain Name to the server,
the server associate a connection to a user and keep looping trough all the connections while sending notification when available for that user.
I'm not sure how many connections I'm able to always keep opened.
Should I use WCF or just make my own sockets system? The logic is pretty basic but it needs to be available on multiple windows platforms with different .NET version.
Do I still need the clients to send back an ACK when received a notification? Or I can just trust the TCP ACK?
Any suggestions will be much appriciated.

Server Push vs Client Pull for Agent-Server Topology

I need to create a system comprising of 2 components:
A single server that process and stores data. It also periodically sends out updates to the agents
Multiple agents that are installed at remote endpoints. These collect data in (often, but not always) long-running operations, and this data needs to get to the server
I'm using C# .NET, and ideally I want to use a standards compliant communications method (i.e. one that could theoritically work with Java too, as we may well also use Java agents in the future). Are there any alternatives to web services? What are my options?
The way I see it I have 3 options using web services, and have made the following observations:
Client pull
No open port required at the agent, as it acts like a client
Would need to poll the server for updates
Server push
Open port at the agent, as it acts like a server
Server must poll agents for results
Hybrid
Open port at the agent, as it acts like both a client and a server
No polling; server pushes out updates when required, client sends results when they are available
The 'hybrid' (where agents are both client and server seems the obvious choice - but this application will typically be installed in enterprise and government environments, and I'm concerned they may have an issue with opening a port at the agent. Am I dwelling too much on this?
Are there any other pros and cons I've missed out?
Our friends at http://www.infrastructures.org swear by pull-based mechanisms: http://www.infrastructures.org/papers/bootstrap/bootstrap.html
A major reason why they prefer client-pull over server-push is that clients may be down, and clients must (in general) apply all the operations pushed by servers. If this criteria isn't important in your case, perhaps their conclusion won't be your conclusion, but I do think it is worth reading the "Push vs Pull" section of their paper to determine for yourself.
I would say that in this day and age you can seriously consider only pull technologies. The problem with push is that clients often are hidden behind Network Address Traversal devices (NAT) like wireless routers, broadband modems or company firewalls and they are, more often than not, unreachable from the server.
Making outbound connections ('phone-home'), specially on well known ports like HTTP/HTTPS can basically be assumed as 'possible' even under most constricted networks.
If you use some kind of messaging server (JMS for Java, not sure for C#) then your messaging server is the only server that needs to open a port and you can have two way communication from your agent to the messaging server and from the server to the messaging server. This would allow you to accomplish the hybrid model without needing to open a port on the agent server.
IMHO, I find your best option is the pull option.. that can satisfy your main system requirements as follow:
The first part: Data needs to get to the server, that's obviously can be done through invoking a web method that send that data as a parameter
2nd part:(Server periodically sends out updates to the agents): You can still do that that thru client (regular) pulls by some sort of a web service method that "asks" for the updates since its last pull (some sort of s time stamp to get the updates it missed)
The hybrid method seems a bit weird to me given that I think of an agent as a part of the system that probably might go "offline" quite often, what will the server then do if that failed? it's usually a tough question/decision, specially if you're not sure if this an intended "going offline" or a system/network failure.. etc

Running a program on multiple PCs

I have some of the basic coding down for the program but I do need assistance with something. My goal is to have an alarm go off on multiple PCs in a network indicating that a certain task needs done. Anyone who receives this alarm may stop it, complete the task and log that they did that. What would be the best way to accomplish this in a network? But not every computer in the network will be running this program, just a few.
You could have the application (which runs on some computers in the network) register to participate in a Multicast address. This would allow the machines in the network to exchange data without the need for a central server.
More information:
IP Multicasting: http://en.wikipedia.org/wiki/Multicast
Multicasting in C#: (CodeProject) http://www.codeproject.com/KB/IP/multicast.aspx
Example project: http://www.nmsl.cs.ucsb.edu/MulticastSocketsBook/csharp_send_receive.zip
You would have the program that generates the alarm send out a multicast message
containing all the information required by the other computers to handle the task.
The computers who can execute the job send back a message and the alarm application
then decides which "client" will eventually execute the task by sending that client a "go ahead and do it" message. Only then the "client" application would actually perform the task and report back when it's finished.
Just an idea.
You could also make a web page on the management server where the visiting users can register for alarms. This would mean that you develop and distribute to one computer instead of x number of computers. The alarm would then go off in your web browser, where the users would also respond.
you can have a process listen on the other PCs on a socket, which triggers the alarm.
http://www.devarticles.com/c/a/C-Sharp/Socket-Programming-in-C-sharp-Part-II/1/
In a corporate environment (or possibly some schools), this is a very common IT problem. You'd use their IT deployment/policy enforcement software to distribute the program.
If you're in control of your network environment, then distribute it however seems fit. An intranet web page where you subscribe to alerts makes sense, as Patrick answered.
Doing a push across the network seems unreliable, and would definitely anger IT staff if you ever moved your program into a less friendly network :) Plus, it simply is the wrong model for the job if your network is the internet.

Creating a heavily restricted server discovery application in c#

I am writing you because of a new problem I need to solve, and I have now been banging my head against a wall for too long now.
Basically, I need to create an application that can take care of the following:
A user starts an app, which sends a broadcast to the subnet, and recieves a response of all servers there with their IP (and some additional info). The user can then select what server he wants to connect to.
Making it work is simple enough, with identifying the subnet, and broadcasting with UDP, and then having a different server application recieving it and sending back a response . The problem lies with these restrictions, that I need to take into consideration:
There will most likely also be clients on the server machines in the network, meaning that we can assume that the application is present on all machines. Every machine needs to have the listener running, and every machine can launch the GUI for selecting a server.
I am only allowed to add one exception to the firewall - an exception that handles both sending out the broadcasts, recieving broadcasts, sending answers and recieving answers.
I should also only be adding one Windows Service
on a server machine, the listener should run as a windows service, so the user won't notice it. Nor will the user notice, that the response is sent back to the client.
On the client machine, the user can start an application, which will notify the application to emmit the broadcast, and will get all the server responses, so the user can choose one to connect to.
Besides from the application that the user launches in order to select a server, there should be no interaction with the user whatsoever. Not even a popup, requesting the user to allow traffic trough the firewall - it should all be automatically
It needs to work on and in between Win XP, Win Vista and Win 7.
I don't know if I am putting too many constrains on myself, but I really hope that I can make the application with these requirements.
I have a few ideas - I just need to figure out how to do it:
Should i make everything into one application, that I add to the firewall exception list, so it will take care of the traffic on both the server and the client machines?
Should I add a custom exception to the firewall, allowing UDP traffic on a specific port, and then have all traffic flow trough that?
Is there a third and better option for managing that?
It is OK to have the service running on both client and server machines. But can it take care of everything for me - like it handling both the broadcast send/recieve and answer send/recieve? And is there any way to extract the information about servers on the network from a service?
I know it is a lot, but I really hope that you will be able to help me out.
let me know if I wasn't clear enough, or if you need further explanations.
I am coding in C# .Net, and I can utilize all I want from the .Net framework. As soon as I have this functionality implemented
All the best
/Sagi
The kind of peer-to-peer networking problems become simple to the point of being trivial if you designate one machine as the master server. It should have a well-known name that all sub-servers can connect to so they can publish (and withdraw) their availability. A client can then send a query request to the same server and get a list of known servers in return.
This can also solve your firewall problem, the master server could be listening on port 80.
Look into the System.Net.PeerToPeer namespace for a p2p solution supported by the framework.
Maybe a UPnP server and client may be a solution to your problem?

Categories

Resources