I use WTelegramClient. The client does not reconnect after the Internet connection is restored.
Showing this:
Connecting to 149.154.167.91:443...
SocketException HostUnreachable (10065): A socket operation was attempted to an unreachable host.
Connecting to [2001:67c:4e8:f004::a]:443...
Connecting to 149.154.167.50:443...
After the connection has been established, transient connection losses should be detected and handled automatically by WTelegramClient:
A reconnection is attempted automatically after a few seconds and pending API calls are automatically resent.
After MaxAutoReconnect reconnection attempts, if the connection can still not be re-established, the client.OnUpdate event receives a ReactorError object, so you can decide what to do.
Now the log you provide doesn't give much context so I presume this happens at the very beginning of opening a session with WTelegramClient.
In this case there is no automatic retry, you should just catch the connection error using a try..catch around the ConnectAsync or LoginUserIfNeeded call, and decide what to do, when to retry the connection.
Related
Please help me to understand grpc client connection error handling.
I've used Micrsoft WCF before. It was easy to try to connect several times and to give up if there is no service accepting incoming connections like below:
// this is pseudo code
int attemptCount = 0;
while (true)
try
{
client.Connect(); // exception is raised if there is not service listening for incoming connection
break;
}
catch (Exception)
{
client.Abort(); // to clear connection faulted state
if (++attempCount == 5)
throw;
Thread.Wait(500); // waiting for service to start
}
5 connection attempts is taken and then client application is terminated if there is no service listening on certain IP:port
This was used when I have client and service started from VisualStudio debug at the same time so sometime client starts first and it has to wait for service to start.
I've tried to do the same using gRPC client but there is no method to reset channel.State from ChannelState.TransientFailure back to working. I know that gRPC makes pauses between connection if something is wrong:
For many non-fatal failures (e.g., TCP connection attempts timing out
because the server is not yet available), the channel may spend
increasingly large amounts of time in this state.
https://grpc.io/grpc-java/javadoc/io/grpc/ConnectivityState.html
I can try to use WaitForStateChangedAsync but how can I configure gRPC client to wait for certain amount of time between reconnection attempts ?
Is there any other way to connect several times and terminate client for gRPC ?
Thank you
gRPC has exponential backoff control on channel reconnection internally.
We do have some backoff parameters, and some of them are configurable by channel arguments.
https://github.com/grpc/grpc/blob/2bd7ad0112f56d2bdbc37d01a431c1e375039f2e/src/core/ext/filters/client_channel/subchannel.cc#L61
But we don't have any parameter to control the max attempt times as far as I know. Please file a feature request on https://github.com/grpc/grpc so that we can follow up.
just searched for a posibble solution to indetify when the client disconnecets.
i found this:
public bool IsConnected( Socket s)
{
try
{
return !(s.Poll(1, SelectMode.SelectRead) &&s.Available == 0);
}
catch (SocketException) { return false; }
}
im using a while loop in my main with thread.sleep(500) and running the Isconnectedmthod it works allright when i run it through the visual studio and when i click stop debugging it actually notify me in the server side program but when i just go to the exe in the bin directory and launch it-it's Indeed notify me for a connection but when i close the program (manually from the 'x' button) or through the task manager theIsConnected method apparently return still true.....
im using a simple tcp connection
client = new TcpClient();
client.Connect("10.0.0.2", 10);
server:
Socket s = tcpClient.Client;
while(true)
{
if (!IsConnected(s))
MessageBox.Show("disconnected");
}
(it's running on a thread btw).
any suggestion guys?
i even tried to close the connection when the client closes:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
client.Close();
s.Close();
Environment.Exit(0);
}
dont know what to do
What you are asking for is not possible. TCP will not report an error on the connection unless an attempt is made to send on the connection. If all your program ever does is receive, it will never notice that the connection no longer exists.
There are some platform-dependent exceptions to this rule, but none involving the simple disappearance of the remote endpoint.
The correct way for a client to disconnect is for it to gracefully close the connection with a "shutdown" operation. In .NET, this means the client code calls Socket.Shutdown(SocketShutdown.Send). The client must then continue to receive until the server calls Socket.Shutdown(SocketShutdown.Both). Note that the shutdown "reason" is generally "send" for the endpoint initiating the closure, and "both" for the endpoint acknowledging and completing the closure.
Each endpoint will detect that the other endpoint has shutdown its end by the completion of a receive operation with 0 as the byte count return value for that operation. Neither endpoint should actually close the socket (i.e. call Socket.Close()) until this two-way graceful closure has completed. I.e. each endpoint has both called Socket.Shutdown() and seen a zero-byte receive operation completion.
The above is how graceful closure works, and it should be the norm for server/client interactions. Of course, things do break. A client could crash, the network might be disconnected, etc. Typically, the right thing to do is to delay recognition of such problems as long as possible; for example, as long as the server and client have no need to actually communicate, then a temporary network outage should not cause an error. Forcing one is pointless in that case.
In other words, don't add code to try to detect a connection failure. For maximum reliability, let the network try to recover on its own.
In some less-common cases, it is desirable to detect connection failures earlier. In these cases, you can enable "keep alive" on the socket (to force data to be sent over the connection, thus detecting interruptions in the connection…see SocketOptionName.KeepAlive) or implement some timeout mechanism (to force the connection to fail if no data is sent after some period of time). I would generally recommend against the use of this kind of technique, but it's a valid approach in some cases.
After SignalR disconnects due to connection error, the state is Disconnected and EnsureReconnecting() may be called to attempt to reconnect. If the reconnect is successful, will the previous proxies still be valid? Or do I need to recreate them using CreateHubProxy()?
I suspect the proxy will still be valid as EnsureReconnecting doesn't do much according to the code: https://github.com/SignalR/SignalR/blob/3a219c101587333d562f04f30903d50ad9773e1c/src/Microsoft.AspNet.SignalR.Client/ConnectionExtensions.cs
I have two mirrored SQL Servers (A and B for example).
I wrote a simple C# program (connect via SqlConnection), which insert rows into DB. When I make failover on server A, the program throws exception, then I try reconnect, and get exception by timeout (**A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 0**).
When I restart the app, the connection is successfully established (to server B). Next, I make failover on B server, and program throws exception, then I try to reconnect, and its work - connection to A witout restarting program.
My connection string:
Data Source=SERVER_A;Failover Partner=SERVER_B;Initial Catalog=TEST_DB;persist security info=True;user id=USER_LOGIN;password=USER_PASS;Connection Timeout=60;
I also try to set big timeout (60 seconds), and try to clear All sqlconnection pools, clear single pool by connection, but it is not working.
Interesting fact: if I use domain login and password, all works fine!
(user SID are same)
Hard to tell what your exact problem is. Perhaps it's that failovers aren't instant, and can't transfer query state - see https://dba.stackexchange.com/questions/27528/can-availability-groups-provide-seamless-failover-with-no-query-failures. If your application immediately retries the query the failover node may therefore still be in the process of taking over and therefore not ready to accept connections.
I run my application on a network and in some cases the client lost connection to the server. After this time, when I wanted to send a message to the server I receive the following error: Operation not allowed on non-connected sockets (something like this).
I thought to create an event for object type TcpClient and when tcp_obj.Connected = false to call a function to discontinue execution of the current code. How could I do this?
Or giving me other suggestios.
Thanks.
I know at least from socket programming in Java that when a client loses connection to the server, the server does not and can not know about it. You need a heartbeat of some sort to detect the early disconnection.
We often use a heartbeat in our client/server applications to detect early disconnections and log them on the server. This way the server can close the associated socket and release the connection back to the pool.
Simply send a command to the client periodically and wait for a response. If no response is garnered within a timeout assume disconnect and close streams.
I would simply first check your connection object to ensure you are connected, prior to attempting to send the message. Also make sure that you are putting your send-logic inside of a try-catch, so that if you do happen to get disconnected mid transmission, you'll be able to resume without blowing your application apart.
Psuedo-Code:
private void SendMessage(string message, Socket socket)
{
if(socket.connectionState = States.Connected)
{
try{
// Attempt to Send
}
catch(SocketException Ex)
{
// Disconenct, Additional Cleanup Etc.
}
}
}
If you are in C#, prior to your connection state changing, you will have a socket disconnected event fire, prior to your connection state changing. Make sure you tie this event up as soon as your socket connects.
Can we know why you use TCP sockets? Is for calling a tcp device o server code?
I recommend you if is for calling a .net server app use Windows Communication Foudation. It is simple to expose services by net.tcp, http, etc.
Regards,
Actually this is a very old problem,
If I understand your question correctly you need a way to know whether you're application is still connected to the server or vice versa.
If so then a workaround is to have a UDP connection just to check the connectivity (overhead I know, but its much better then polling on Connected state), you could check just before you send you're data.
Since UDP is not Connection oriented you don't need to be connected when you send the data