Private
Public Access
1
0

Supports polling for updates

This commit is contained in:
James Magahern
2018-11-17 01:07:55 -08:00
parent 464e9fe22c
commit ddec4be8d6
12 changed files with 316 additions and 11 deletions

View File

@@ -8,7 +8,9 @@
#import "MBIMBridge.h"
#import "MBIMBridgeOperation.h"
#import "MBIMConcurrentHTTPServer.h"
#import "MBIMHTTPConnection.h"
#import "MBIMUpdateQueue.h"
#import "hooking.h"
#import <CocoaHTTPServer/HTTPServer.h>
@@ -22,7 +24,7 @@
static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
@interface MBIMBridge (/* INTERNAL */)
@property (nonatomic, strong) HTTPServer *httpServer;
@property (nonatomic, strong) MBIMConcurrentHTTPServer *httpServer;
@property (nonatomic, strong) NSOperationQueue *operationQueue;
- (instancetype)_init;
@@ -52,6 +54,7 @@ static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
[sDaemonListener addHandler:self];
_operationQueue = [[NSOperationQueue alloc] init];
_operationQueue.maxConcurrentOperationCount = 5;
}
return self;
@@ -115,7 +118,19 @@ static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
{
NSLog(@"Received message from chat with GUID: %@", [[notification object] guid]);
// TODO: Notify observers or something
IMChat *chat = [notification object];
IMMessage *message = [[notification userInfo] objectForKey:IMChatValueKey];
if (chat && message) {
if (![message isFromMe]) {
MBIMUpdateItem *updateItem = [[MBIMUpdateItem alloc] init];
updateItem.changedChat = chat;
updateItem.message = message;
[[MBIMUpdateQueue sharedInstance] enqueueUpdateItem:updateItem];
} else {
// TODO: care about messages from me?
}
}
}
- (void)_chatRegistryDidLoad:(NSNotification *)notification
@@ -133,7 +148,7 @@ static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
- (void)startWebServer
{
self.httpServer = [[HTTPServer alloc] init];
self.httpServer = [[MBIMConcurrentHTTPServer alloc] init];
[self.httpServer setConnectionClass:[MBIMHTTPConnection class]];
[self.httpServer setPort:8080];

View File

@@ -0,0 +1,17 @@
//
// MBIMConcurrentHTTPServer.h
// kordophoned
//
// Created by James Magahern on 11/16/18.
// Copyright © 2018 James Magahern. All rights reserved.
//
#import <CocoaHTTPServer/HTTPServer.h>
NS_ASSUME_NONNULL_BEGIN
@interface MBIMConcurrentHTTPServer : HTTPServer
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,23 @@
//
// MBIMConcurrentHTTPServer.m
// kordophoned
//
// Created by James Magahern on 11/16/18.
// Copyright © 2018 James Magahern. All rights reserved.
//
#import "MBIMConcurrentHTTPServer.h"
@implementation MBIMConcurrentHTTPServer
- (id)init
{
self = [super init];
if (self) {
connectionQueue = dispatch_queue_create("net.buzzert.MBIMConcurrentHTTPConnectionQueue", DISPATCH_QUEUE_CONCURRENT);
}
return self;
}
@end

View File

@@ -13,6 +13,7 @@
@implementation MBIMHTTPConnection {
NSMutableData *_bodyData;
MBIMBridgeOperation *_currentOperation;
}
- (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)path
@@ -37,11 +38,11 @@
NSString *endpointName = [url lastPathComponent];
Class operationClass = [MBIMBridgeOperation operationClassForEndpointName:endpointName];
if (operationClass != nil) {
MBIMBridgeOperation *operation = [[operationClass alloc] initWithRequestURL:url completion:completion];
operation.requestBodyData = _bodyData;
_currentOperation = [[operationClass alloc] initWithRequestURL:url completion:completion];
_currentOperation.requestBodyData = _bodyData;
[[[MBIMBridge sharedInstance] operationQueue] addOperation:operation];
dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)));
[[[MBIMBridge sharedInstance] operationQueue] addOperation:_currentOperation];
dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60.0 * NSEC_PER_SEC)));
} else {
response = [[HTTPErrorResponse alloc] initWithErrorCode:404];
}
@@ -68,4 +69,10 @@
[_bodyData appendData:postDataChunk];
}
- (void)die
{
[_currentOperation cancel];
[super die];
}
@end

View File

@@ -0,0 +1,30 @@
//
// MBIMUpdateQueue.h
// kordophoned
//
// Created by James Magahern on 11/16/18.
// Copyright © 2018 James Magahern. All rights reserved.
//
#import <IMCore/IMCore.h>
#import <IMFoundation/IMFoundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MBIMUpdateItem : NSObject
@property (nonatomic, strong) IMChat *changedChat;
@property (nonatomic, strong) IMMessage *message;
@end
typedef void (^MBIMUpdateConsumer)(MBIMUpdateItem *item);
@interface MBIMUpdateQueue : NSObject
+ (instancetype)sharedInstance;
- (void)addConsumer:(MBIMUpdateConsumer)consumer;
- (void)enqueueUpdateItem:(MBIMUpdateItem *)item;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,61 @@
//
// MBIMUpdateQueue.m
// kordophoned
//
// Created by James Magahern on 11/16/18.
// Copyright © 2018 James Magahern. All rights reserved.
//
#import "MBIMUpdateQueue.h"
@implementation MBIMUpdateQueue {
dispatch_queue_t _accessQueue;
NSMutableArray *_consumers;
}
+ (instancetype)sharedInstance
{
static MBIMUpdateQueue *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (instancetype)init
{
self = [super init];
if (self) {
_accessQueue = dispatch_queue_create("net.buzzert.MBIMUpdateQueue", DISPATCH_QUEUE_SERIAL);
_consumers = [[NSMutableArray alloc] init];
}
return self;
}
- (void)addConsumer:(MBIMUpdateConsumer)consumer
{
__weak NSMutableArray *consumers = _consumers;
dispatch_async(_accessQueue, ^{
[consumers addObject:consumer];
});
}
- (void)enqueueUpdateItem:(MBIMUpdateItem *)item
{
__weak NSMutableArray *consumers = _consumers;
dispatch_async(_accessQueue, ^{
for (MBIMUpdateConsumer consumer in consumers) {
consumer(item);
}
[consumers removeAllObjects];
});
}
@end
@implementation MBIMUpdateItem
@end

View File

@@ -8,6 +8,7 @@
#import "MBIMMessagesListOperation.h"
#import "MBIMHTTPUtilities.h"
#import "IMMessageItem+Encoded.h"
#import <IMCore/IMCore.h>
@@ -52,10 +53,7 @@
NSMutableArray *messages = [NSMutableArray array];
for (IMMessageItem *imMessage in [[chat chatItems] messages]) {
NSMutableDictionary *messageDict = [NSMutableDictionary dictionary];
messageDict[@"text"] = [[imMessage body] string];
messageDict[@"date"] = MBIMWebServerFormatRFC822([imMessage time]);
messageDict[@"sender"] = [imMessage sender];
NSDictionary *messageDict = [imMessage mbim_dictionaryRepresentation];
[messages addObject:messageDict];
}

View File

@@ -0,0 +1,17 @@
//
// MBIMUpdatePollOperation.h
// kordophoned
//
// Created by James Magahern on 11/16/18.
// Copyright © 2018 James Magahern. All rights reserved.
//
#import "MBIMBridgeOperation.h"
NS_ASSUME_NONNULL_BEGIN
@interface MBIMUpdatePollOperation : MBIMBridgeOperation
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,39 @@
//
// MBIMUpdatePollOperation.m
// kordophoned
//
// Created by James Magahern on 11/16/18.
// Copyright © 2018 James Magahern. All rights reserved.
//
#import "MBIMUpdatePollOperation.h"
#import "MBIMUpdateQueue.h"
#import "IMMessageItem+Encoded.h"
@implementation MBIMUpdatePollOperation
+ (void)load { [super load]; }
+ (NSString *)endpointName
{
return @"pollUpdates";
}
- (void)main
{
MBIMUpdateConsumer consumer = ^(MBIMUpdateItem *nextUpdateItem) {
NSDictionary *updateDict = @{
@"guid" : [[nextUpdateItem changedChat] guid],
@"message" : [[nextUpdateItem message] mbim_dictionaryRepresentation]
};
MBIMJSONDataResponse *response = [MBIMJSONDataResponse responseWithJSONObject:updateDict];
self.serverCompletionBlock(response);
};
[[MBIMUpdateQueue sharedInstance] addConsumer:consumer];
}
// TODO: cancel needs to remove the consumer from the update queue
@end