I have a functioning extension that communicates with native host C# app. Looking for a way to automatically re-establish a connection with the C# app after I close and re-open it. Any help greatly appreciated.
Native messaging means only Chrome can start a host instance when it "connects". It's a misnomer, since connect() means "launch a new copy and talk to it".
There is no way to "attach" to an already-running process. If you close the host, stdio pipe is broken the Port object fires onDisconnect event. Then you need to re-launch the host from the extension to be able to talk to it.
How about asking the server if it's still here (i.e. once every 30 seconds)
if you get no answer given a certain delay (=> timeout) drop the connection and create a new one.
Th delay must not be too fast, to avoid resettong connections when there is only a 'lag spike'
Related
I have a small client/server application. I was using a hand-coded TCP connection to allow the client to control the server, but now I've converted it to WCF. This saved me a whole bunch of code, but it also gave me a whole new set of problems to fix...
The latest problem is that after a while, the server disconnects the client. I do not want this to ever happen, under any circumstances. Currently the client gets about a quarter of the way through its run, and then explodes with fire because the server has dropped the connection. I need to stop this happening.
I was able to write a trivial WCF client/server pair that replicates the problem. It seems that if the client calls a method, waits 15 minutes, and then calls a second method, the second call throws an exception babbling something about the socket having been closed. If I reduce the delay, everything works fine.
I read in another answer somewhere that setting ReceiveTimeout should fix this. However, when I tried it, this only fixes the problem under .NET; when running under Mono, it still breaks. Since Mono is the actual target platform, this isn't very helpful.
(Think about SSH - you would not want an SSH server to disconnect you just because you didn't type anything for a while. Perhaps you issued a long-running shell command or something... Just because the server hasn't received any data from you doesn't mean nothing is happening! It certainly doesn't mean your connection should get dropped...)
All code is C#. The server is a self-hosting console app. The client is also a console app. All configuration is in code. Binding is NetTcpBinding with default settings.
What can I do to allow the client to run to completion successfully?
I have a few ideas, but none of them are pretty:
Manually send heartbeat messages. (Yuck!)
Detect disconnection and automatically reconnect? (Again, yuck.)
Turn on "reliable mode". (I'm guessing that since the server deliberately ends the session, this won't help.)
Create one connection per method call. (That's going to be quite a lot of code...)
Stop using WCF?
In the end I "fixed" this by having the client make a new connection for every single command. This works acceptably because the client doesn't send commands all that often. It's annoying having to write the connect/disconnect code a dozen times though...
I wrote a small daemon application in .NET last year that basically launches a Minecraft server, and provides a web based GUI to manage it. It does other things such as restart the process if it crashes, and other useful functions.
Our company recently heard of a french hosting company that had setup their servers in a way that when the last player disconnected, the server would shutdown until another player joined. Now, I have been thinking about how this might be possible, and wanted to see what the thoughts on it were. My daemon can already tell how many players are connected, so that is not an issue.
My psuedo thought process is...
Last Player disconnects from server
Daemon takes over listening on the server port for connections
Upon incoming connection, save the connection packet data and restart the server sub-process
Pass the save connection on to the Minecraft java process
I can't really figure out how to handle the last step yet, but that is the best solution I have come up with. Any thoughts or suggestions?
Perhaps you'll have more players wanting to connect at once, so you might have problems with that approach (cuz i'm guessing your server won't start instantaneously).
You should have a daemon waiting for connections and putting them on a queue or something, until the server starts, and feed it then, the connections (or connection packets or whatever). After the server is started, and all connections have been forwarded to it, get your daemon to "stop" (a.k.a die or stop clogging the port)
Hope this helps.
You can not "save" a TCP network connection and then redirect it to a different process. The only way to implement this would be to let your tool act as a proxy server that accepts all connections and sends all data to the server running on a different port.
In such a set-up you could start the server upon the first incoming connection.
The only other solution would require direct read access to the network interface the way e.g. is used by Wireshark/Pcap library. They you would be able to detect TCP SYN packets and start the server when they are coming in.
I have a problem, I've developed a Client and Server wrapper for my personal use, but unfortunately due to insufficient knowledge in network programming, I have TIME_WAIT problems during connect on the client. My client tries to make multiple connections to the same host within short period of time now, I have found out that the main reason for that is because I'm trying to reuse the socket and it goes to TIME_WAIT state because I'm closing the connection without graceful shutdown. I would like to know the correct pattern to close connection using .NET sockets in case I'm using 'Async' APIs intensively i.e. functions like ConnectAsync, AcceptAsync, SendAsync, ReceiveAsync, DisconnectAsync (DisconnectAsync - reuses socket)
I have found out that it is impossible to prevent TIME_WAIT. Either server or client will have the problem any way, depending only on who initiates a closure of the connection first. If it's the client who closes the connection, there will be no TIME_WAIT on server. If it's the server who closes first, than there will be no TIME_WAIT on client. So the only option that is left to do is using SO_REUSEADDR, but in this case it is still impossible to use the reused address for contacting previously disconnected host
You can use SO_REUSEADDR on the socket to get around this. See Socket.SetSocketOption for details, it's the ReuseAddress option you need to set.
By the way you don't really mean reuse the socket do you? once you get an error, you have to close it and open a new one.
I've got a project where I'm hitting a bunch of custom Windows Performance Counters on multiple servers and aggregating them into a database. If a server is down, I want to skip it, and just continue on with my day.
Currently I'm checking to see if a server is live by doing a DirectoryInfo on a share that I've got to look at later in the process anyways, then checking the .Exists property.This is my current code snippet for testing:
DirectoryInfo di = new DirectoryInfo(machine.Share_Path);
if (!di.Exists)
{
log.Warn("Could not access " + machine.Name + "! Maybe its down?");
continue; // Skips to the next server in my loop where this snippet exists.
}
This works, but its pretty slow. It takes about 68 seconds on average for the di.Exists bit to finish its work, and I ideally need to know within a second whether or not a server is accessible. Pinging also isn't an option since a server can be pingable but not "live" in our environment.
I'm still kind of fresh to the .NET world, so I'm open to any advice people can offer.
Thanks in advance.
-Weegee
Ping First, Ask Questions Later
Why not ping first, and then do the di.Exists if you get a response?
That would allow you to fail early in the case that is not reachable, and not waste the time for machines that are down hard.
I have, in fact, used this method successfully before.
MSDN Ping Documentation
Paralellize
Another option you have is to paralellize the checking, and action on the servers as they are known to be available.
You could use the Paralell.ForEach() method, and use a thread-safe queue along with a simple consumer thread to do the required action. Combined with the checking method above, this could alleviate almost all of your bottleneck on the up/down checking.
Knock on the Door
Yet another method would be to ckeck if the required remote service is running (either by hitting its port directly or by querying it with WMI).
Since WMI is almost always running when a machine is up, your connection should be very quick to either succeed or fail.
The only "quick" way I think to see if it's up without relying on ping would be to create a socket, and see if you can actually connect to the port of the service you're trying to reach.
This would be the equivalent of telnet servername 135 to see if it's up.
Specifically...
Create a .NET TCP socket client (System.Net.Sockets.TcpClient)
Call BeginConnect() as an asynchronous operation, to connect to the server in question on one of the RPC ports that your directory exists code would use anyway (TCP 135, 139, or 445).
If you don't hear back from it within X milliseconds, call Close() to cancel the connection.
Disclaimer: I have no idea what effect this would have on any threat/firewall protection that may see this type of Connect / Disconnect with no data sent activity as a threat.
Opening Socket to a specific port usually does the trick. If you really want it to be fast, be sure to set the NoDelay property on the new socket (Nagle algorithm) so there is no buffering.
Fast will largely depend on latency but this is probably the fastest way I know to connect to an endpoint. It's pretty simple to parallelize using the async methods. How fast you can check will largely depend on your network topology but in tests for 1000 servers (latency between 0-75ms) I've been able to get connectivity state in ~30 seconds. Not scientific data at all but should give you the idea.
Also, don't ever do this through UNC file shares because if the server no longer exists you will have a lot of dangling connections that take forever to timeout. So if you have a lot of servers with invalid DNS records and you try to poll them you will bring Windows down completely over time. Things like File.Exists and any file access will cause this.
The "Full-Blown" option would be to install a monitoring tool like SCOM (System Center Operations Manager), this has an SDK you can use to query SCOM for (performance) and maintenance information avout machines being monitored. Might be a bridge to far though....
Telnet is another option. Try telnetting to the target machine to see if it responds.
Create a small Windows Service that you install on your target machine, have the sys admin stop it when they perform maintenance on the target machine (just use batch file to net stop / net start the service)
Is it possible to get all open or cached gprs connections on windows mobile and programmatic force them to close?
Ive been looking at connection manager api but cant seem to find methods I to do this.
Regards
Tony
Connection Manager can be notified that you're no longer using the connection by calling ConnMgrReleaseConnection, but that does not forcibly close the connection. It is closed based on the lifetime caching defined in the registry (HKEY_LOCAL_MACHINE\Comm\ConnMgr\Planner\Settings), as well as any info passed in the Release request. (BTW, these APIs are wrapped in the OpenNETCF ConnectionManager objects in the SDF).
The only way to forcibly close the connection is to use RAS to enumerate all device connections, find the one you're after, and close it. Be aware that if you do this, ConnectionManager doesn't know that it's been closed, so it's going to be upset the next time it tries to use that connection. Typically it will get an error internally and try to open a new connection again and all is well, but YMMV.