- Update
This commit is contained in:
1 parent
d281d765ea
commit
5b074a5176
1261 files changed
+199158
-7303
No files matched your search
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Simple XMPP module that tracks average bandwidth of the xmpp stream.
|
||||
*
|
||||
* For now, this is a really simple module.
|
||||
* But perhaps in the future, as developers adapt this module,
|
||||
* they will open source their additions and improvements.
|
||||
**/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "XMPP.h"
|
||||
|
||||
#define _XMPP_BANDWIDTH_MONITOR_H
|
||||
|
||||
@interface XMPPBandwidthMonitor : XMPPModule
|
||||
|
||||
@property (readonly) double outgoingBandwidth;
|
||||
@property (readonly) double incomingBandwidth;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,191 @@
|
||||
#import "XMPPBandwidthMonitor.h"
|
||||
#import "XMPPLogging.h"
|
||||
#import "NSXMLElement+XMPP.h"
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
// Log levels: off, error, warn, info, verbose
|
||||
#if DEBUG
|
||||
static const int xmppLogLevel = XMPP_LOG_LEVEL_VERBOSE;
|
||||
#else
|
||||
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
|
||||
#endif
|
||||
|
||||
|
||||
@implementation XMPPBandwidthMonitor
|
||||
{
|
||||
dispatch_source_t timer;
|
||||
|
||||
uint64_t lastNumberOfBytesSent;
|
||||
uint64_t lastNumberOfBytesReceived;
|
||||
|
||||
double smoothedAverageOutgoingBandwidth;
|
||||
double smoothedAverageIncomingBandwidth;
|
||||
}
|
||||
|
||||
- (double)outgoingBandwidth
|
||||
{
|
||||
__block double result = 0.0;
|
||||
|
||||
dispatch_block_t block = ^{
|
||||
result = smoothedAverageOutgoingBandwidth;
|
||||
};
|
||||
|
||||
if (dispatch_get_specific(moduleQueueTag))
|
||||
block();
|
||||
else
|
||||
dispatch_sync(moduleQueue, block);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (double)incomingBandwidth
|
||||
{
|
||||
__block double result = 0.0;
|
||||
|
||||
dispatch_block_t block = ^{
|
||||
result = smoothedAverageIncomingBandwidth;
|
||||
};
|
||||
|
||||
if (dispatch_get_specific(moduleQueueTag))
|
||||
block();
|
||||
else
|
||||
dispatch_sync(moduleQueue, block);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)updateBandwidth
|
||||
{
|
||||
uint64_t currentNumberOfBytesSent = 0;
|
||||
uint64_t currentNumberOfBytesReceived = 0;
|
||||
|
||||
[xmppStream getNumberOfBytesSent:¤tNumberOfBytesSent numberOfBytesReceived:¤tNumberOfBytesReceived];
|
||||
|
||||
double currentOutgoingBandwidth = currentNumberOfBytesSent - lastNumberOfBytesSent; // Bytes per second
|
||||
double currentIncomingBandwidth = currentNumberOfBytesReceived - lastNumberOfBytesReceived; // Bytes per second
|
||||
|
||||
if (smoothedAverageOutgoingBandwidth || smoothedAverageIncomingBandwidth)
|
||||
{
|
||||
// Apply Brown's Simple Exponential Smoothing algorithm
|
||||
|
||||
double smoothingFactor = 0.3;
|
||||
|
||||
smoothedAverageOutgoingBandwidth = (smoothingFactor * currentOutgoingBandwidth)
|
||||
+ ((1 - smoothingFactor) * smoothedAverageOutgoingBandwidth);
|
||||
|
||||
smoothedAverageIncomingBandwidth = (smoothingFactor * currentIncomingBandwidth)
|
||||
+ ((1 - smoothingFactor) * smoothedAverageIncomingBandwidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No previous data
|
||||
|
||||
smoothedAverageOutgoingBandwidth = currentOutgoingBandwidth;
|
||||
smoothedAverageIncomingBandwidth = currentIncomingBandwidth;
|
||||
}
|
||||
|
||||
lastNumberOfBytesSent = currentNumberOfBytesSent;
|
||||
lastNumberOfBytesReceived = currentNumberOfBytesReceived;
|
||||
|
||||
XMPPLogVerbose(@"Bandwidth = Out(%.0f, %.0f) In(%.0f, %.0f)",
|
||||
currentOutgoingBandwidth, smoothedAverageOutgoingBandwidth,
|
||||
currentIncomingBandwidth, smoothedAverageIncomingBandwidth);
|
||||
}
|
||||
|
||||
- (void)startTimer
|
||||
{
|
||||
if (timer == NULL)
|
||||
{
|
||||
uint64_t numberOfBytesSent = 0;
|
||||
uint64_t numberOfBytesReceived = 0;
|
||||
|
||||
[xmppStream getNumberOfBytesSent:&numberOfBytesSent numberOfBytesReceived:&numberOfBytesReceived];
|
||||
|
||||
lastNumberOfBytesSent = numberOfBytesSent;
|
||||
lastNumberOfBytesReceived = numberOfBytesReceived;
|
||||
|
||||
smoothedAverageOutgoingBandwidth = 0.0;
|
||||
smoothedAverageIncomingBandwidth = 0.0;
|
||||
|
||||
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, moduleQueue);
|
||||
|
||||
dispatch_source_set_event_handler(timer, ^{ @autoreleasepool {
|
||||
|
||||
[self updateBandwidth];
|
||||
|
||||
}});
|
||||
|
||||
NSTimeInterval interval = 1.0; // Update every 1 second(s)
|
||||
|
||||
uint64_t intervalTime = interval * NSEC_PER_SEC;
|
||||
dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, intervalTime);
|
||||
|
||||
dispatch_source_set_timer(timer, startTime, intervalTime, 0.25);
|
||||
dispatch_resume(timer);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopTimer
|
||||
{
|
||||
if (timer)
|
||||
{
|
||||
lastNumberOfBytesSent = 0;
|
||||
lastNumberOfBytesReceived = 0;
|
||||
|
||||
smoothedAverageOutgoingBandwidth = 0.0;
|
||||
smoothedAverageIncomingBandwidth = 0.0;
|
||||
|
||||
dispatch_source_cancel(timer);
|
||||
#if !OS_OBJECT_USE_OBJC
|
||||
dispatch_release(timer);
|
||||
#endif
|
||||
timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)activate:(XMPPStream *)aXmppStream
|
||||
{
|
||||
if ([super activate:aXmppStream])
|
||||
{
|
||||
if ([xmppStream isConnected])
|
||||
{
|
||||
[self startTimer];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)deactivate
|
||||
{
|
||||
dispatch_block_t block = ^{ @autoreleasepool {
|
||||
|
||||
[self stopTimer];
|
||||
[super deactivate];
|
||||
}};
|
||||
|
||||
if (dispatch_get_specific(moduleQueueTag))
|
||||
block();
|
||||
else
|
||||
dispatch_sync(moduleQueue, block);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark XMPPStream Delegate
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)xmppStreamDidStartNegotiation:(XMPPStream *)sender;
|
||||
{
|
||||
[self startTimer];
|
||||
}
|
||||
|
||||
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
|
||||
{
|
||||
[self stopTimer];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in new issue
Block a user