.net Remoting: Detect if a server isn't running - c#

I'm working on an app that uses .net remoting for IPC.
When my client app starts up, it uses the following code to connect to the server:
chnl = gcnew HttpChannel();
ChannelServices::RegisterChannel(chnl, false);
IPCObjectInstance = (BaseRemoteObject)Activator.GetObject(
typeof(BaseRemoteObject),
"http://localhost:1237/MyRemoteObject.soap");
And, when I make my function call, I use the following code:
BaseRemoteObject.GetFileTextDelegate svd = new BaseRemoteObject.GetFileTextDelegate(IPCObjectInstance, BaseRemoteObject.GetFileText);
AsyncCallback callback = new AsyncCallback(this, &ClientGUI.RecievedStringText);
IAsyncResult arValSet = svd.BeginInvoke(callback, null);
This code works great as is. However, I want my client to detect whether or not the server is running when it boots, and display the appropriate error message.
When the server isn't running, the client waits for about 3 seconds, before throwing a web exception (shown at bottom). There is no error "location", so I'm not sure of where to put the try\catch block.
What is the best way to detect my server not running?
Thanks!

It should work to do a try/catch around your BeginInvoke line.
But my suggestion would be to create a Status method which you call synchrously instead of async, and do try/catch around that call instead. It can be a dummy method doing nothing.
It also possible to open a tcp connection to the remote server on the port specified and see if you get a connection. But this would be much like try/catch around a remoting call.

Related

c# TCP/IP client is connected to internet or not

can i get client is offline or online in new thread in server side ?
it's mean when a client connected to my server i want check in new thread that The client is still online or not .
It looks like you have the url incorrect for 'TcpClient', and you are not calling the 'Connect' method of the 'TcpClient' instance... here's the corrected version..see this here on MSDN....If I were you, I would wrap this up in a try/catch clause to see the exact error... nitpicky aside, if you are using disposable objects, wrap them up in a using clause also!

How to close C++ REST Sdk websocket?

I'm using cpprestsdk on the client and .net core 2.1 on the server side. Everything works except the closing part.
// C++
web::websockets::client::websocket_callback_client _client;
//connecting and working with websocket...
_client.close().wait();
// C#
while (!Socket.CloseStatus.HasValue)
{
//sending/reciving data
}
await Socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Connection closed", CancellationToken.None);
The issue is that the _client.close().wait(); never exits. The server gets the close request and calls CloseOutputAsync successfully. And I can't figure out why it never exits _client.close().wait();. It looks like there is some issue with the handshake between C++ and .net core implementations and didn't manage to make a workaround. Is there any way of forcing _client.close().wait(); to close the connection and do not wait for the handshake part from the server? Or is there is something wrong with the server code of closing a web socket?
It was my own mistake. I have set the _client.set_close_handler(...) which use lock_guard. This cases a deadlock since this mutex was locked during the close() call.

Do I need to close the connection to a WCF service from a console that exits straight away?

I have a console app that I want to do a "fire-and-forget" call to a WCF service, and then close down without waiting for a response. It is just supposed to initiate a cleanup job. The job can take several hours to finish, so I don't want the console app to stay open and wait for it.
I have added "IsOneWay=true" to the methods in the contract, but the console app still waits for the task to finish before doing client.close() and exiting.
If I remove the client.Close() then the console app works the way I want, but I am not sure if the channel will remain open even though the console app is not running anymore?
Here is my console app code:
static void Main(string[] args)
{
Console.WriteLine("Starting Cleanup");
var client = new IntegrationWcfServiceClient(EndPointConfigurationName);
try
{
client.ExecuteCleanup();
//client.Close();
}
catch (Exception ex)
{
client.Abort();
WriteLineRed($"Couldn't start cleanup: {ex.Message}");
return;
}
WriteLineGreen("Cleanup started successfully");
}
And here is the operation contract code:
[OperationContract(IsOneWay = true)]
void ExecuteCleanup();
There are few things you need to consider while making oneway call.
From the book programming WCF services.
Ideally, when the client calls a one-way method, it should be blocked only for the
briefest moment required to dispatch the call. However, in reality, one-way calls do not equate to asynchronous calls. When one-way calls reach the service, they may not be
dispatched all at once but may instead be buffered on the service side to be dispatched
one at a time, according to the service’s configured concurrency mode behavior
Although one-way operations do not return values or exceptions from the service itself,
it’s wrong to perceive them as a one-way street or a “black hole” from which nothing
can come out. The client should still expect exceptions from a one-way call, and can
even deduce that the call failed on the service. When dispatching a one-way operation,
any error because of communication problems (such as a wrong address or the host
being unavailable) will throw an exception on the side of the client trying to invoke the
operation.
If I remove the client.Close() then the console app works the way I want, but I am not sure if the channel will remain open even though the console app is not running anymore?
A one-way call is not fire-and-forget in nature, since the client can discover
that something went wrong on the service during a one-way invocation.
Here you are tring to invoke invoke a one-way operation asynchronously and hence you are not able to close the connection or proxy.
[OperationContract(IsOneWay = true,AsyncPattern = true)]
IAsyncResult ExecuteCleanup(AsyncCallback callback,object asyncState);
client.ExecuteCleanup(,null,null);
Note:If you dont want to complicate things ,then make sure ExecuteCleanup is the last call in your service and later you can close which will not affect later operations.
Possible implementation How to properly close a client proxy (An existing connection was forcibly closed by the remote host)?

What is the best approach for an asynchronous callback/event from gSOAP server?

I am designing a webservice interface for use between a Windows CE device and a PC. The Windows CE device is server and the PC is client.
I have decided to use the gSOAP library to implement the server and I am using .NET/C# for the client. I have followed the approach described here and everything is working well.
My question is about how to best implement an asynchronous callback/event from the server to the client. I can think of two methods:
Continuously polling the server for active events
A blocking method that keeps the connection open until an event occurs
I have currently chosen option 2 and it seems to be working well. I use an asynchronous method in the client and therefore get a callback when the method completes, i.e. when an event occurs on the Windows CE device. I then immediately call the same method again so it is ready for the next event.
Example server method (no error handling):
int ns__WaitForEvent(struct soap* soap, int *eventId)
{
WaitForSingleObject(hMyServerEvent, INFINITE);
*eventId = GetCurrentEventId();
return SOAP_OK;
}
Example client (no error handling):
private void SubscribeToServerEvents()
{
var server = new MyMethods.ServicePortTypeClient(
new BasicHttpBinding(),
new EndpointAddress(myIpAddress));
AsyncCallback cb = this.Callback;
server.BeginWaitForEvent(cb, server);
}
private void Callback(IAsyncResult ar)
{
var server = (MyMethods.ServicePortType)ar.AsyncState;
var result = server.EndWaitForEvent(ar);
// Do stuff with result
}
The server must be multi-threaded for this approach to work, and the number of clients should be limited so the server does not have a large number of threads hanging with blocking methods. In my case none of these issues are a problem - it is simple to setup a multi-threaded server using gSOAP and there will only ever be one client (which I control) attached to each server.
Are there any significant disadvantages to this approach? Can you suggest a better solution?
I suggest to turn the WinCE device into a webclient instead of a webserver and the PC into a server, that will be notified on something happens on the client. It is more natural this approach, you can still use gSoap for a soap client. On the PC you should have a web-server like Apache or IIS installed, or you could make a Windows server that will host an embedded light webserver.

client-server question

If i have a client that is connected to a server and if the server crashes, how can i determine, form my client, if the connection is off ? the idea is that if in my client's while i await to read a line from my server ( String a = sr.ReadLine(); ) and while the client is waiting to recieve that line , the server crashes , how do i close that thread that contains my while ?
Many have told me that in that while(alive) { .. } I should just change the alive value to true , but if my program is currently awaiting for a line to read, it won't get to exit the while because it will be trapped at sr.ReadLine() .
I was thinking that if i can't send a line to the server i should just close the client thread with .abort() . Any Ideas ?
Have a TimeOut parameter in ReadLine method which takes a TimeSpan value and times out after that interval if the response is not received..
public string ReadLine(TimeSpan timeout)
{
// ..your logic.
)
For an example check these SO posts -
Implementing a timeout on a function returning a value
Implement C# Generic Timeout
Is the server app your own, or something off the shelf?
If it's yours, send a "heart beat" every couple of seconds to let the clients know that the connection and service are still alive. (This is a bit more reliable than just seeing if the connection is closed since it may be possible for the connection to remain open while the server app is locked.)
That the server crashes has nothing to do with your clients. There are several external factors that can make the connection go down: The client is one of them, internet/lan problems is another one.
It doesn't matter why something fails, the server should handle it anyway. Servers going down will make your users scream ;)
Regarding multi threading, I suggest that you look at the BeginXXX/EndXXX asynchronous methods. They give you much more power and a more robust solution.
Try to avoid any strategy that relies on thread abort(). If you cannot avoid it, make sure you understand the idiom for that mechanism, which involves having a separate appdomain and catching ThreadAbortException
If the server crashes I imagine you will have more problems than just fixing a while loop. Your program may enter an unstable state for other reasons. State should not be overlooked. That being said, a nice "server timed out" message may suffice. You could take it a step further and ping, then give a slightly more advanced message "server appears to be down".

Categories

Resources