针对 ejabberd 快速重新连接和推送模式的 XMPP 框架中的流程一扩展
Process One Extension in XMPP Framework For ejabberd Fast Reconnect and Push Mode
我在使用为 ejabberd 制作的名为 ProcessOne 的 XMPPFramework 扩展时遇到困难。
我正在尝试将 ProcessOne 扩展用于快速重新连接和推送模式
// Process One Fast Reconnect & Push Standby Mode //
xmppProcessOne = [[XMPPProcessOne alloc] initWithDispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)];
[xmppProcessOne addDelegate:self delegateQueue:dispatch_get_main_queue()];
xmppProcessOne.pushConfiguration = [self setPushconfiguration];
[xmppProcessOne activate:_xmppStream];
根据 ejabberd 文档,我必须在流功能确认后发送重新绑定数据包。
在 XMPPRebindAuthentication 的实现下,此扩展中有一个方法可用。我无法理解如何调用此方法。
我认为 XMPPFramework 中 Extensions/ProcessOne 支持会话重新绑定的代码不完整并且可以按原样工作。
这是我在 XMPPFramework 上建议的一个应该有效的补丁:https://github.com/processone/XMPPFramework/commit/67a20c28b28ca49667ca11012bb2a11373023057
至少我可以使用以下示例客户端从那里进行重新绑定:
- AppDelegate.h
//
// AppDelegate.h
//
// Created by Mickaël Rémond on 07/03/16.
//
#import <UIKit/UIKit.h>
#import <XMPPFramework/XMPPRoster.h>
#import <XMPPFramework/XMPPRosterCoreDataStorage.h>
#import <XMPPFramework/XMPPProcessOne.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, XMPPRosterDelegate, XMPPStreamDelegate>
@property (strong, nonatomic) UIWindow *window;
/* XMPP related properties */
@property (nonatomic, strong) XMPPStream *xmppStream;
@property (nonatomic, strong) XMPPRoster *xmppRoster;
@property (nonatomic, strong) XMPPProcessOne *xmppProcessOne;
@property (nonatomic, strong) XMPPRosterCoreDataStorage *xmppRosterStorage;
@end
- AppDelegate.m
//
// AppDelegate.m
//
// Created by Mickaël Rémond on 07/03/16.
//
#import "AppDelegate.h"
#import "DDLog.h"
#import "DDTTYLogger.h"
#import "XMPPLogging.h"
@interface AppDelegate ()
- (void)setupStream;
- (BOOL)connect;
@end
@implementation AppDelegate
static NSString * const kMyJid = @"test@example.net";
static NSString * const kMyPass = @"passw0rd";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Log all XMPP traffic for debugging
[DDLog addLogger:[DDTTYLogger sharedInstance] withLogLevel:XMPP_LOG_FLAG_SEND_RECV];
[self setupStream];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self connect];
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#pragma mark == Setup XMPP parameters ==
- (void)setupStream {
_xmppStream = [XMPPStream new];
_xmppRosterStorage = [XMPPRosterCoreDataStorage new];
_xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:_xmppRosterStorage];
[_xmppRoster activate:_xmppStream];
[_xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppStream addDelegate:self.xmppProcessOne delegateQueue:dispatch_get_main_queue()];
[_xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppStream setMyJID:[XMPPJID jidWithString:kMyJid]];
_xmppProcessOne = [[XMPPProcessOne alloc] initWithDispatchQueue:dispatch_get_main_queue()];
// TODO: Method to generate default push configuration
NSXMLElement *pushConfiguration = [XMPPProcessOne pushConfigurationContainer];
[pushConfiguration addChild:[XMPPProcessOne keepaliveWithMax:30]]; // Seconds
[pushConfiguration addChild:[XMPPProcessOne sessionWithDuration:300]]; // Seconds
_xmppProcessOne.pushConfiguration = pushConfiguration;
[_xmppProcessOne addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppProcessOne activate:self.xmppStream];
}
#pragma mark == XMPP DELEGATES ==
- (void)xmppStreamDidConnect:(XMPPStream *)sender {
if ([self.xmppStream supportsRebind] && self.xmppProcessOne.savedSessionJID != nil) {
NSError *error = nil;
_xmppRoster.autoFetchRoster = NO;
if (![[self xmppStream] rebindSession:self.xmppProcessOne.savedSessionID forJID:self.xmppProcessOne.savedSessionJID withError:&error]) {
NSLog(@"Could not send session rebind successfully: %@", error);
}
} else {
NSError *error = nil;
_xmppRoster.autoFetchRoster = YES;
if (![[self xmppStream] authenticateWithPassword:kMyPass error:&error]) {
NSLog(@"Could not send standard password auth info: %@", error);
}
}
}
// Rebind failed, try standard auth
- (void)xmppStream:(XMPPStream *)sender runFallbackAuthentication:(NSXMLElement *)error {
NSLog(@"Rebind failed: %@", error);
NSError *error2 = nil;
_xmppRoster.autoFetchRoster = YES;
if (![[self xmppStream] authenticateWithPassword:kMyPass error:&error2]) {
NSLog(@"did not authenticate %@", error2);
}
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error {
NSLog(@"Authentication failed: %@", error);
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
NSLog(@"Authentication successfull");
[[self xmppStream] sendElement:[XMPPPresence presence]];
}
/* Initiate TCP connection to XMPP server */
- (BOOL)connect {
if (!self.xmppStream.isConnected) {
if (![self.xmppStream isDisconnected]) {
return YES;
}
NSError *error = nil;
if (![self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]) {
NSLog(@"Error connecting to XMPP server");
} else {
NSLog(@"Successfully connected");
}
return YES;
} else {
return YES;
}
}
@end
我在使用为 ejabberd 制作的名为 ProcessOne 的 XMPPFramework 扩展时遇到困难。
我正在尝试将 ProcessOne 扩展用于快速重新连接和推送模式
// Process One Fast Reconnect & Push Standby Mode //
xmppProcessOne = [[XMPPProcessOne alloc] initWithDispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)];
[xmppProcessOne addDelegate:self delegateQueue:dispatch_get_main_queue()];
xmppProcessOne.pushConfiguration = [self setPushconfiguration];
[xmppProcessOne activate:_xmppStream];
根据 ejabberd 文档,我必须在流功能确认后发送重新绑定数据包。 在 XMPPRebindAuthentication 的实现下,此扩展中有一个方法可用。我无法理解如何调用此方法。
我认为 XMPPFramework 中 Extensions/ProcessOne 支持会话重新绑定的代码不完整并且可以按原样工作。
这是我在 XMPPFramework 上建议的一个应该有效的补丁:https://github.com/processone/XMPPFramework/commit/67a20c28b28ca49667ca11012bb2a11373023057
至少我可以使用以下示例客户端从那里进行重新绑定:
- AppDelegate.h
//
// AppDelegate.h
//
// Created by Mickaël Rémond on 07/03/16.
//
#import <UIKit/UIKit.h>
#import <XMPPFramework/XMPPRoster.h>
#import <XMPPFramework/XMPPRosterCoreDataStorage.h>
#import <XMPPFramework/XMPPProcessOne.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, XMPPRosterDelegate, XMPPStreamDelegate>
@property (strong, nonatomic) UIWindow *window;
/* XMPP related properties */
@property (nonatomic, strong) XMPPStream *xmppStream;
@property (nonatomic, strong) XMPPRoster *xmppRoster;
@property (nonatomic, strong) XMPPProcessOne *xmppProcessOne;
@property (nonatomic, strong) XMPPRosterCoreDataStorage *xmppRosterStorage;
@end
- AppDelegate.m
//
// AppDelegate.m
//
// Created by Mickaël Rémond on 07/03/16.
//
#import "AppDelegate.h"
#import "DDLog.h"
#import "DDTTYLogger.h"
#import "XMPPLogging.h"
@interface AppDelegate ()
- (void)setupStream;
- (BOOL)connect;
@end
@implementation AppDelegate
static NSString * const kMyJid = @"test@example.net";
static NSString * const kMyPass = @"passw0rd";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Log all XMPP traffic for debugging
[DDLog addLogger:[DDTTYLogger sharedInstance] withLogLevel:XMPP_LOG_FLAG_SEND_RECV];
[self setupStream];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self connect];
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#pragma mark == Setup XMPP parameters ==
- (void)setupStream {
_xmppStream = [XMPPStream new];
_xmppRosterStorage = [XMPPRosterCoreDataStorage new];
_xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:_xmppRosterStorage];
[_xmppRoster activate:_xmppStream];
[_xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppStream addDelegate:self.xmppProcessOne delegateQueue:dispatch_get_main_queue()];
[_xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppStream setMyJID:[XMPPJID jidWithString:kMyJid]];
_xmppProcessOne = [[XMPPProcessOne alloc] initWithDispatchQueue:dispatch_get_main_queue()];
// TODO: Method to generate default push configuration
NSXMLElement *pushConfiguration = [XMPPProcessOne pushConfigurationContainer];
[pushConfiguration addChild:[XMPPProcessOne keepaliveWithMax:30]]; // Seconds
[pushConfiguration addChild:[XMPPProcessOne sessionWithDuration:300]]; // Seconds
_xmppProcessOne.pushConfiguration = pushConfiguration;
[_xmppProcessOne addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppProcessOne activate:self.xmppStream];
}
#pragma mark == XMPP DELEGATES ==
- (void)xmppStreamDidConnect:(XMPPStream *)sender {
if ([self.xmppStream supportsRebind] && self.xmppProcessOne.savedSessionJID != nil) {
NSError *error = nil;
_xmppRoster.autoFetchRoster = NO;
if (![[self xmppStream] rebindSession:self.xmppProcessOne.savedSessionID forJID:self.xmppProcessOne.savedSessionJID withError:&error]) {
NSLog(@"Could not send session rebind successfully: %@", error);
}
} else {
NSError *error = nil;
_xmppRoster.autoFetchRoster = YES;
if (![[self xmppStream] authenticateWithPassword:kMyPass error:&error]) {
NSLog(@"Could not send standard password auth info: %@", error);
}
}
}
// Rebind failed, try standard auth
- (void)xmppStream:(XMPPStream *)sender runFallbackAuthentication:(NSXMLElement *)error {
NSLog(@"Rebind failed: %@", error);
NSError *error2 = nil;
_xmppRoster.autoFetchRoster = YES;
if (![[self xmppStream] authenticateWithPassword:kMyPass error:&error2]) {
NSLog(@"did not authenticate %@", error2);
}
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error {
NSLog(@"Authentication failed: %@", error);
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
NSLog(@"Authentication successfull");
[[self xmppStream] sendElement:[XMPPPresence presence]];
}
/* Initiate TCP connection to XMPP server */
- (BOOL)connect {
if (!self.xmppStream.isConnected) {
if (![self.xmppStream isDisconnected]) {
return YES;
}
NSError *error = nil;
if (![self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]) {
NSLog(@"Error connecting to XMPP server");
} else {
NSLog(@"Successfully connected");
}
return YES;
} else {
return YES;
}
}
@end