iOS - XMPP 재연결 및 기타 질문(완료)
socket
연결이 끊어지고 ping
패키지 서버가 응답하지 않으며 서버가 자발적으로 하선을 제거하고 앞뒤로 데이터 패키지를 해석할 수 없는 등 사용자의 체험에 영향을 줄 수 있다.이런 상황에서 보통 재연결 메커니즘을 설계한다. 긴 연결이 끊어질 때마다 어떤 방식에 따라 재연결 조작을 시작하고 사용자가 아무런 감지도 하지 않은 상황에서 다시 긴 연결을 구축하는 것이야말로 좋은 체험이다.
XMPP
프레임워크에서 당신은 스스로 중련을 실현할 필요가 없다. 프레임워크 안에서 중련의 방법을 제공했다. 이런 종류는 바로 XMPPReconnect
이다. 당신은 몇 가지 절차만 거치면 실현할 수 있다.@interface XMPPManager ()
@property (nonatomic, strong) XMPPStream *xmppStream;
/** */
@property (nonatomic, strong) XMPPAutoPing *xmppAutoPing;
/** */
@property (nonatomic, strong) XMPPReconnect *xmppReconnect;
@end
@implementation XMPPManager {
/** , 0 */
NSInteger reconnectCount;
/** ping , 0 */
NSInteger pingTimeoutCount;
/** , */
dispatch_queue_t _streamQueue;
}
// , ...
// init , setupStream , ...
/** Setup the XMPP stream */
- (void)setupStream {
_xmppStream = [[XMPPStream alloc] init];
[_xmppStream addDelegate:self delegateQueue: _streamQueue];
_xmppAutoPing = [[XMPPAutoPing alloc] init];
_xmppAutoPing.pingInterval = 20.f; //
[_xmppAutoPing activate:_xmppStream];
[_xmppAutoPing addDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
_xmppReconnect = [[XMPPReconnect alloc] init];
_xmppReconnect.autoReconnect = YES;
_xmppReconnect.reconnectDelay = 0.f;// , ,
_xmppReconnect.reconnectTimerInterval = 3.f;// 3
[_xmppReconnect activate:_xmppStream];
[_xmppReconnect addDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
}
이렇게 다시 연결된 클래스는 초기화되고, 이어서 프록시 리셋을 쓰고, 연결을 끊으면 리셋 방법을 사용합니다.
......
#pragma mark - XMPPReconnectDelegate
- (void)xmppReconnect:(XMPPReconnect *)sender didDetectAccidentalDisconnect:(SCNetworkConnectionFlags)connectionFlags {
QCLog(@"xmpp 。");
}
- (BOOL)xmppReconnect:(XMPPReconnect *)sender shouldAttemptAutoReconnect:(SCNetworkConnectionFlags)connectionFlags {
reconnectCount++;
self.isReconnecting = YES;
QCLog(@"xmpp ... %@ ", @(reconnectCount));
if (reconnectCount < 5) {
}
else if (reconnectCount >= 5 && reconnectCount <= 10) {
[self.xmppReconnect resSetupReconnectTimerWithTimerInterval:9.f];
}
else if (reconnectCount > 10 && reconnectCount <= 15) {
[self.xmppReconnect resSetupReconnectTimerWithTimerInterval:15.f];
}
else {
[self reconnectImmediately];
}
return YES;
}
......
- (void)reconnectImmediately {
self.xmppReconnect.reconnectTimerInterval = 3.f;
reconnectCount = 0;
[self.xmppReconnect stop];
[self.xmppReconnect manualStart];
}
여기에 설명이 필요합니다. 연결을 잃었을 때 즉시 재연결을 시작합니다. 앞의 5회는 3초마다 다시 연결합니다. 뒤의 5회는 9초마다 다시 연결합니다. 뒤의 5회는 15초마다 다시 연결합니다. 만약 이 15번이 모두 실패한다면 이 규칙에 따라 다시 연결합니다.나는 중복 접속을 몇 번 하지 않고 버렸다. 이렇게 하면 서버에 일정한 압력을 가할 수 있고 이해득실을 스스로 고려할 수 있다.생각해 보니 이렇게 여러 번 실패했으니 연결이 안 되겠지, 다시 연결할 필요는 없을 거야.열 번의 연결이 실패하면 다시 연결하지 않도록 할 수 있다.사용자가 자발적으로 어떤 조작을 촉발할 때 다시 연결을 시작하거나 앱 앞 백그라운드 전환할 때 다시 연결을 합니다.이것들은 단지 개인적인 생각일 뿐이다.
XMPP
클래스에서 동적 재연결 시간 간격을 조정하는 방법을 확장했습니다. 방법은 다음과 같습니다.- (void)resSetupReconnectTimerWithTimerInterval:(NSTimeInterval)interval
{
//
if (reconnectTimer != NULL)
{
if (reconnectTimer)
{
dispatch_source_cancel(reconnectTimer);
reconnectTimer = NULL;
}
}
if ((reconnectDelay <= 0.0) && (reconnectTimerInterval <= 0.0))
{
// All timed reconnect attempts are disabled
return;
}
reconnectTimerInterval = interval;
reconnectTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, moduleQueue);
dispatch_source_set_event_handler(reconnectTimer, ^{ @autoreleasepool {
[self maybeAttemptReconnect];
}});
#if !OS_OBJECT_USE_OBJC
dispatch_source_t theReconnectTimer = reconnectTimer;
dispatch_source_set_cancel_handler(reconnectTimer, ^{
XMPPLogVerbose(@"dispatch_release(reconnectTimer)");
dispatch_release(theReconnectTimer);
});
#endif
dispatch_time_t startTime;
if (reconnectDelay > 0.0) {
startTime = dispatch_time(DISPATCH_TIME_NOW, (reconnectDelay * NSEC_PER_SEC));
} else {
startTime = dispatch_time(DISPATCH_TIME_NOW, (reconnectTimerInterval * NSEC_PER_SEC));
}
uint64_t intervalTime;
if (reconnectTimerInterval > 0.0) {
intervalTime = reconnectTimerInterval * NSEC_PER_SEC;
} else {
intervalTime = 0.0;
}
dispatch_source_set_timer(reconnectTimer, startTime, intervalTime, 0.25);
dispatch_resume(reconnectTimer);
}
XMPPReconnect
에 대해 제 이쪽의 방법은 클라이언트가 20s마다 ping
패키지를 보내고 클라이언트가 두 번ping
패키지를 서버에 보낸 후에 서버가 되돌아오는 ping
패키지를 받지 못하면 수동으로 연결을 끊습니다(즉시 다시 연결됩니다).......
#pragma mark - XMPPAutoPingDelegate
- (void)xmppAutoPingDidReceivePong:(XMPPAutoPing *)sender{
// 1 , ping ,
if (pingTimeoutCount > 0) {
pingTimeoutCount = 0;
}
}
- (void)xmppAutoPingDidTimeout:(XMPPAutoPing *)sender {
// , disconnect
pingTimeoutCount++;
if (pingTimeoutCount >= 2) {
[self.xmppStream disconnect];
}
}
......
여러 개의 장치 로그인에 대해서도 한 네티즌이 질문한 것이다. 한 장치에 어떤 계정
pong
이 로그인한 후에 한 장치에 이 계정을 로그인하면 원래의 계정은 서버에서 보낸 오류 메시지를 받을 수 있다. 물론 전제는 리셋을 쓰는 것이다.다음과 같은 방법으로 뺏겼는지 확인할 수 있다.- (void)xmppStream:(XMPPStream *)sender didReceiveError:(NSXMLElement *)error {
//
NSString *conflict = [[error elementForName:@"conflict"] stringValue];
if (conflict) {
// , ....
// , ,
}
}
XMPP
의 디버깅 로그에 대해 메시지를 받을 때 로그가 없는 것은 답답한 일이다. 로그를 정확하게 출력하는 것은 각종 난치병을 해결하는 데 매우 유리하다.기억하십니까? 이 글에서 XMPP 프레임워크는 세 개의 소스 라이브러리를 인용했는데 그 중 하나가 바로 Cocoa Lumberjack입니다. 이것이 바로 우리가 사용해야 할 디버깅 도구입니다. 여러 번 시도해 보았지만 틀림없습니다.지금 그것을 어떻게 사용하는지 봅시다.(이 일지의 사용도 오랫동안 괴롭혔다...)먼저 XMPP
류의 XMPPManager
파일의 머리 위에 다음과 같이 쓰십시오.#import "DDLog.h"
#import "DDTTYLogger.h"
#import "DDFileLogger.h"
#ifndef QCConsoleLoggingEnabled
// 1 ,0
#define QCConsoleLoggingEnabled 0
#endif
#define QCContext 102333
#define QCLogAsync YES
#if QCConsoleLoggingEnabled
#define QCLogObjc(flg, frmt, ...) LOG_OBJC_MAYBE(QCLogAsync, logLevelQC, flg, QCContext, frmt, ##__VA_ARGS__)
#define QCLogTrace() QCLogObjc(LOG_FLAG_VERBOSE, @"%@: %@", THIS_FILE, THIS_METHOD)
#ifndef QCLogLevelll
#define QCLogLevelll LOG_LEVEL_VERBOSE
#endif
// Log levels : off, error, warn, info, verbose
static const int logLevelQC = QCLogLevelll;
#else
#define QCLogObjc(flg, frmt, ...) {}
#define QCLogTrace() {}
#endif
로그를 인쇄할지 여부를 제어하는 방법을 하나 더 추가합니다. 초기화
.m
할 때 호출하면 됩니다.- (void)addLogs {
#if QCConsoleLoggingEnabled
// log
DDTTYLogger *logger = [DDTTYLogger sharedInstance];
[DDLog addLogger:logger withLevel:DDLogLevelAll];
#endif
// log,
DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling
fileLogger.logFileManager.maximumNumberOfLogFiles = 7;
[DDLog addLogger:fileLogger];
}
백그라운드 실행 정보메시지 영수증에 관해서?(사실은 간단하게 말할 수 있는...)메시지 재발급에 대해서?미안하지만, 나는 하지 않았다. 왜냐하면 이미 늦었기 때문이다. 사실 이전에 나는 할 시간이 매우 많았다. 단지... 됐어, 말하지 않겠다.
XMPP, 사랑했었어... 미워했었어...
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.