Spring Scheduled Task, strange behavior - spring

I have a Scheduled task which runs every 800 seconds from a server towards its clients to see if they are online. If they are not, it will send me an email, and will send an email when they are back online.
So, this is the scheduled task
#Scheduled(fixedDelay = 800000)
public void pingAllClients() {
logger.debug("Schedule pingClients");
List<Client> clients = clientService.findAllClients();
Iterator<Client> it = clients.iterator();
while (it.hasNext()) {
Client client = it.next();
String ip = client.getCurrentIp();
int idClient = client.getIdClient();
boolean isOnline = client.isOnline();
try {
boolean reachable = reachClient.isReachable(ip);
if (reachable) {
if (!isOnline) {
logger.debug("Client " + idClient + " back online");
client.setOnline(true);
clientService.updateClient(client);
smtp.sendEmail(serverName, ip, true);
}
} else {
logger.debug("Client " + idClient + " not available");
if (isOnline) {
client.setOnline(false);
clientService.updateClient(client);
smtp.sendEmail(serverName, ip, false);
}
}
} catch (Exception e) {
logger.error("Errore", e);
}
}
}
}
reachClient.isReachable(ip) is this method:
public boolean isReachable(String ip){
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(ip, 22), 50*1000);
return true;
} catch (IOException e) {
return false;
} finally {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
So, it should be: every 800 seconds i loop my clients, see if the are reachable or not, and if they change status, i will receive an email. In the email i print the date/time of the request.
It always happens that i get an email from an offline client and soon after (2-10 seconds) an email it is back online, as, for the same client, i'm getting 2 emails in a single iteration, how is it possibile? Each client should be reachable or not for every loop, not both...
The last 2 emails I got are (6 seconds delay)
Client 192.168.42.13 is offline - Date: 11-12-2016 17:14:30
Client 192.168.42.13 back online - Date: 11-12-2016 17:14:36

Related

Xamarin: multiple request network pop ups in android 10, when try to connect to wifi in IOT module

I am working on an IOT module with wifi connection,I am testing using a samsung with android 10.
The chip is a ESP8266.The Wi-Fi signal, does not have an internet connection.
the project is developed in xamarin.
The problem, is when I try to connect to the device's signal. When I'm making the connection request, multiple pop ups appear in the device, requesting the connection, and it does not wait until it is connected, immediately the device launches the connection requests again and again, finally crash.
when i'm debugging, the NetworkAvailable runs, but even the phone does not finish connecting to the signal, the phone lunch a new request network again, don't wait until you are actually connected, and I don't know why multiple requests are launched.
Here is my code.
public async Task<bool> Connect(string WiFiName, string WifiPassword)
{
bool result = false;
var formattedSsid = $"\"{WiFiName}\"";
var formattedPassword = $"\"{WifiPassword}\"";
try
{
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
var wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder()
.SetSsid(WiFiName)
.SetWpa2Passphrase(WifiPassword)
.Build();
var networkRequest = new NetworkRequest.Builder()
.AddTransportType(TransportType.Wifi) // we want WiFi
.SetNetworkSpecifier(wifiNetworkSpecifier) // we want _our_ network
.Build();
UnregisterNetworkCallback(_networkCallback);
_networkCallback = new NetworkCallback()
{
NetworkAvailable = network =>
{
result = true;
autoResetEvent.Set(); //signal
},
NetworkUnavailable = () =>
{
result = false;
autoResetEvent.Set(); //signal
},
};
connectivityManager.RequestNetwork(networkRequest, _networkCallback);
autoResetEvent.WaitOne();
}
catch (Exception e)
{
Crashes.TrackError(e);
}
finally
{
}
return result;
}
private void UnregisterNetworkCallback(NetworkCallback _networkCallback)
{
if (_networkCallback != null)
{
try
{
_connectivityManager.UnregisterNetworkCallback(_networkCallback);
}
catch (Exception) {
} finally
{
_networkCallback = null;
}
}
}
public class NetworkCallback : ConnectivityManager.NetworkCallback
{
public Action<Network> NetworkAvailable { get; set; }
public Action NetworkUnavailable { get; set; }
public NetworkCallback()
{
}
public override void OnAvailable(Network network)
{
try
{
WiFiAndroid.connectivityManager.BindProcessToNetwork(null);
WiFiAndroid.connectivityManager.BindProcessToNetwork(network);
}
catch (Exception ex)
{
var error = ex;
}
}
public override void OnUnavailable()
{
base.OnUnavailable();
NetworkUnavailable?.Invoke();
}
}
the image, is the request that is throw over and over again.

WebSocketSharp with BinanceAPI

I have a connection with binanceApi and I have a disconnect problem,
the API disconnects and I don't know the reason, I wanna keep the connection alive until I have the orders in position. I will post my code, maybe someone can help me.
I already have created another two projects with websocketsharp on localhost to test and all disconnects fire normally.
https://pastebin.com/edit/2Mbh1X4p
public class WSMonitorada
{
public WebSocket ws;
public Usuario User;
public Timer timerKeepAlive = new Timer();
public WSMonitorada(Usuario user, string key)
{
timerKeepAlive.Interval = TimeSpan.FromMinutes(15).TotalMilliseconds;
timerKeepAlive.Elapsed += (object source, ElapsedEventArgs e) =>
{
BinanceUserDataStream.KeepAlive(User.BinanceAPIKey, user.BinanceAPISecret);
};
timerKeepAlive.Start();
ws = new WebSocket("wss://stream.binance.com:9443/ws/" + key);
ws.WaitTime = TimeSpan.FromSeconds(5);
ws.Log.Level = LogLevel.Trace;
ws.Log.File = "C:\\LogConexao\\" + user.nome + ".txt";
//log file never show close event
ws.OnOpen += (sender, e) =>
{
//logic here wors perfect
};
ws.EmitOnPing = true;
ws.OnMessage += (sender, e) =>
{
if (e.IsPing)
{
ws.Ping();
return;
}
//logic here wors perfect
}
ws.OnClose += (sender, e) =>
{
// i have a logic here to analyse if i have a opened order and reconnect again but event never fire
ws.Connect();
};
ws.Connect();
}
}
I think your Ping is not correct. The server waits for 'pong' message
UPD
According to binance docs =)

SSE server sending events in a batch on final close

I have a Jersey server running locally, it exposes a SSE resource just like the examples here: https://jersey.github.io/documentation/latest/sse.html. I have a local webpack Angular app, that binds to the exposed GET endpoint and listens for data.
On the GET, I start up a thread to send notifications at regular intervals over 6-8 seconds. I don't see anything on the client UNTIL the EventOutput object is closed.
What am I doing wrong, and how can I fix this?
The server code WORKS with just a simple curl, i.e.:
curl http://localhost:8002/api/v1/notify
But on both Chrome and Safari the following code exhibits the behavior
Client (TypeScript):
this.evSource = new EventSource('http://localhost:8002/api/v1/notify');
this.evSource.addEventListener(
'event',
(x => console.log('we have ', x))
);
this.evSource.onmessage = (data => console.log(data));
this.evSource.onopen = (data => console.log(data));
this.evSource.onerror = (data => {
console.log(data);
this.evSource.close();
});
Server (Java):
// cache callback
public void eventCallback(Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>> events) {
for (CacheEntryEvent<? extends Integer, ? extends Integer> x : events) {
LOGGER.info("{} Sending the following value: " + x.getValue(), Thread.currentThread().getId());
final OutboundEvent sseEvent = new OutboundEvent.Builder().name("event")
.data(Integer.class, x.getValue()).build();
this.broadcaster.broadcast(sseEvent);
}
}
#GET
#Produces(SseFeature.SERVER_SENT_EVENTS)
#ApiOperation(value = "Setup SSE pipeline", notes = "Sets up the notification pipeline for clients to access")
#ApiResponses(value = {
#ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED,
message = "Missing, bad or untrusted cookie"),
#ApiResponse(code = HttpURLConnection.HTTP_OK,
message = "Events streamed successfully")
})
#Timed
#ResponseMetered
public EventOutput registerNotificationEvents(
#HeaderParam(SseFeature.LAST_EVENT_ID_HEADER) String lastEventId,
#QueryParam(SseFeature.LAST_EVENT_ID_HEADER) String lastEventIdQuery) {
if (!Strings.isNullOrEmpty(lastEventId) || !Strings.isNullOrEmpty(lastEventIdQuery)) {
LOGGER.info("Found Last-Event-ID header: {}", !Strings.isNullOrEmpty(lastEventId) ? lastEventId : lastEventIdQuery );
}
LOGGER.info("{} Received request", Thread.currentThread().getId());
this.continuation = true;
final EventOutput output = new EventOutput();
broadcaster.add(output);
Random rand = new Random();
IntStream rndStream = IntStream.generate(() -> rand.nextInt(90));
List<Integer> lottery = rndStream.limit(15).boxed().collect(Collectors.toList());
IgniteCache<Integer, Integer> cache = this.ignite.cache(topic_name);
executorService.execute(() -> {
try {
lottery.forEach(value -> {
try {
TimeUnit.MILLISECONDS.sleep(500);
LOGGER.info("{} Sending the following value to Ignite: " + value + " : " + count++, Thread.currentThread().getId());
if (!cache.isClosed()) {
cache.put(1, value);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
TimeUnit.MILLISECONDS.sleep(500);
continuation = false;
TimeUnit.MILLISECONDS.sleep(500);
if (!output.isClosed()) {
// THIS is where the client sees ALL the data broadcast
// in one shot
output.close();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
});
LOGGER.info("{} Completing request", Thread.currentThread().getId());
return output;
}
}
Looks like http://github.com/dropwizard/dropwizard/issues/1673 captures the problem. GZip default won't flush even if upper levels ask for it. Solution is something like
((AbstractServerFactory)configuration.getServerFactory()).getGzipFilterFactory().setSyncFlush(true);
will enable flushing to synchronize with GZip if disabling GZip all up is not an option

Configuring Skype for Business delegates using UCMA

I have been struggling to programatically add a delegate to a user (boss/admin scenario).
After running my test code in the boss sfb client the admin appears as a delegate however, in the admin's sfb client the boss does not appear under the section "people I manage calls for". I verified in the rtc frontend database that the delegation is configured, however the admin subscription record does not list the boss. Below is the code I used to achieve this.
Any ideas why the admin sfb client is not being notified of the new delegation?
Thanks,
Simon
1) add delegate-management
public void SendAddDelegate()
{
string body = string.Format($"<setDelegates xmlns=\"http://schemas.microsoft.com/2007/09/sip/delegate-management\" version=\"1\"><delegate uri=\"sip:admin#example.com\" action=\"add\"/></setDelegates>");
byte[] encBody = Encoding.UTF8.GetBytes(body);
RealTimeAddress rta = new RealTimeAddress("sip:boss#example.com");
System.Net.Mime.ContentType contentType = new System.Net.Mime.ContentType("application/msrtc-setdelegate+xml")
endpoint.InnerEndpoint.BeginSendMessage(MessageType.Service, rta, contentType, encBody, SendAddDelegateManagementMessageComplete, null);
}
private void SendAddDelegateManagementMessageComplete(IAsyncResult result)
{
try
{
SipResponseData srd = endpoint.InnerEndpoint.EndSendMessage(result);
logger.Debug($"srd.ResponseCode - {srd.ResponseCode}");
}
catch (Exception exc)
{
logger.Error("Exception SendMessageComplete with message - {0}", exc.Message);
}
}
2) Publish presence
public void PublishRoutingCategory(string delegateUri)
{
//routes not created here for sample brevity
routes.DelegateRingEnabled = true;
routes.Delegates.Add(delegateUri);
routes.SimultaneousRingEnabled = true;
routes.SimultaneousRing.Add(delegateUri);
routes.SkipPrimaryEnabled = true;
routes.ForwardAudioAppInvitesEnabled = true;
try
{
userEndpoint.LocalOwnerPresence.BeginPublishPresence(new PresenceCategory[] { routes }, PublishComplete, null);
}
catch (Exception exc)
{
logger.Error("Unknown error - {0}", exc.Message);
}
}
private void PublishComplete(IAsyncResult result)
{
try
{
endpoint.LocalOwnerPresence.EndPublishPresence(result);
}
catch (Exception exc)
{
logger.Error("Error Publish Complete- {0}", exc.Message);
}
}

Android BluetoothLE Disconnection issue

I'm rebuilding a ble app that will commnunicate with a bluetooth device.
The code I found had this odd method called after closing the connection,
bluetoothGatt.disconnect();
which will call the onStateChangeCallback.
The method is this;
private void refreshDeviceCache(final BluetoothGatt gatt) {
int cnt = 0;
boolean success = false;
try {
if (gatt != null) {
final Method refresh = gatt.getClass().getMethod("refresh");
if (refresh != null) {
success = (Boolean) refresh.invoke(gatt);
while (!success && cnt < 100) {
success = (Boolean) refresh.invoke(gatt);
cnt++;
}
Log.e(TAG, "retry refresh : " + cnt + " " + success);
}
}
} catch (Exception e) {
Log.e(TAG, "5", e);
}
}
I can't totally understand what this code will do, but in conclusion, it slows down the connection after the disconnection. It does not slow down the disconnection.
I really can't understand this because after I get the BluetoothProfile.STATE_DISCONNECTED, I will close the bluetoothGatt, and on the broadCastReceiver, unbind the service and close the service itself.
On the connection phase, the service will be recreated.
What line of that code on disconnection may slow down the connection? Please help me out with this.

Resources