More pinging logic
This commit is contained in:
parent
7f679ba5ed
commit
455c8c520b
|
@ -9,6 +9,9 @@ public extension LokiAPI {
|
|||
let data: LosslessStringConvertible
|
||||
/// The time to live for the message in milliseconds.
|
||||
let ttl: UInt64
|
||||
/// Wether this message is a ping.
|
||||
/// This should always be false unless it is from p2p pinging logic.
|
||||
let isPing: Bool
|
||||
/// When the proof of work was calculated, if applicable.
|
||||
///
|
||||
/// - Note: Expressed as milliseconds since 00:00:00 UTC on 1 January 1970.
|
||||
|
@ -25,9 +28,13 @@ public extension LokiAPI {
|
|||
let wrappedMessage = try LokiMessageWrapper.wrap(message: signalMessage, timestamp: timestamp)
|
||||
let data = wrappedMessage.base64EncodedString()
|
||||
let destination = signalMessage["destination"] as! String
|
||||
|
||||
var ttl = LokiAPI.defaultMessageTTL
|
||||
if let messageTTL = signalMessage["ttl"] as? UInt, messageTTL > 0 { ttl = UInt64(messageTTL) }
|
||||
return Message(destination: destination, data: data, ttl: ttl, timestamp: nil, nonce: nil)
|
||||
|
||||
let isPing = signalMessage["isPing"] as! Bool
|
||||
|
||||
return Message(destination: destination, data: data, ttl: ttl, isPing: isPing)
|
||||
} catch let error {
|
||||
Logger.debug("[Loki] Failed to convert Signal message to Loki message: \(signalMessage)")
|
||||
return nil
|
||||
|
@ -40,17 +47,19 @@ public extension LokiAPI {
|
|||
/// - destination: The destination
|
||||
/// - data: The data
|
||||
/// - ttl: The time to live
|
||||
public init(destination: String, data: LosslessStringConvertible, ttl: UInt64) {
|
||||
public init(destination: String, data: LosslessStringConvertible, ttl: UInt64, isPing: Bool = false) {
|
||||
self.destination = destination
|
||||
self.data = data
|
||||
self.ttl = ttl
|
||||
self.isPing = isPing
|
||||
}
|
||||
|
||||
/// Private init for setting proof of work. Use `calculatePoW` to get a message with these fields
|
||||
private init(destination: String, data: LosslessStringConvertible, ttl: UInt64, timestamp: UInt64?, nonce: String?) {
|
||||
private init(destination: String, data: LosslessStringConvertible, ttl: UInt64, isPing: Bool, timestamp: UInt64?, nonce: String?) {
|
||||
self.destination = destination
|
||||
self.data = data
|
||||
self.ttl = ttl
|
||||
self.isPing = isPing
|
||||
self.timestamp = timestamp
|
||||
self.nonce = nonce
|
||||
}
|
||||
|
@ -64,7 +73,7 @@ public extension LokiAPI {
|
|||
DispatchQueue.global(qos: .default).async {
|
||||
let now = NSDate.ows_millisecondTimeStamp()
|
||||
if let nonce = ProofOfWork.calculate(data: self.data as! String, pubKey: self.destination, timestamp: now, ttl: self.ttl) {
|
||||
let result = Message(destination: self.destination, data: self.data, ttl: self.ttl, timestamp: now, nonce: nonce)
|
||||
let result = Message(destination: self.destination, data: self.data, ttl: self.ttl, isPing: self.isPing, timestamp: now, nonce: nonce)
|
||||
seal.fulfill(result)
|
||||
} else {
|
||||
seal.reject(Error.proofOfWorkCalculationFailed)
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
|
||||
extension LokiAPI {
|
||||
|
||||
private static let messageSender: MessageSender = SSKEnvironment.shared.messageSender
|
||||
|
||||
/// The amount of time before pinging when a user is set to offline
|
||||
private static let offlinePingTime = 2 * kMinuteInterval
|
||||
|
||||
/// A p2p state struct
|
||||
internal struct P2PDetails {
|
||||
var address: String
|
||||
var port: UInt32
|
||||
var isOnline: Bool
|
||||
var timerDuration: Double
|
||||
var pingTimer: WeakTimer? = nil
|
||||
var pingTimer: Timer? = nil
|
||||
|
||||
var target: Target {
|
||||
return Target(address: address, port: port)
|
||||
|
@ -68,6 +70,23 @@ extension LokiAPI {
|
|||
// TODO: Ping the contact
|
||||
}
|
||||
|
||||
@objc public static func setOnline(_ isOnline: Bool, forContact pubKey: String) {
|
||||
guard var details = contactP2PDetails[pubKey] else { return }
|
||||
|
||||
let interval = isOnline ? details.timerDuration : offlinePingTime
|
||||
|
||||
// Setup a new timer
|
||||
details.pingTimer?.invalidate()
|
||||
details.pingTimer = WeakTimer.scheduledTimer(timeInterval: interval, target: self, userInfo: nil, repeats: true) { _ in ping(contact: pubKey) }
|
||||
details.isOnline = isOnline
|
||||
|
||||
contactP2PDetails[pubKey] = details
|
||||
}
|
||||
|
||||
@objc public static func ping(contact pubKey: String) {
|
||||
|
||||
}
|
||||
|
||||
/// Set the Contact p2p details
|
||||
///
|
||||
/// - Parameters:
|
||||
|
@ -109,7 +128,7 @@ extension LokiAPI {
|
|||
return nil
|
||||
}
|
||||
|
||||
return LokiAddressMessage(in: thread, address: ourAddress.address, port: ourAddress.port)
|
||||
return LokiAddressMessage(in: thread, address: ourAddress.address, port: ourAddress.port, isPing: false)
|
||||
}
|
||||
|
||||
/// Send a `Loki Address` message to the given thread
|
||||
|
|
|
@ -51,16 +51,6 @@ import PromiseKit
|
|||
}.map { Set($0) }
|
||||
}
|
||||
|
||||
public static func ping(_ hexEncodedPublicKey: String) -> Promise<Set<Promise<RawResponse>>> {
|
||||
let isP2PMessagingPossible = false
|
||||
if isP2PMessagingPossible {
|
||||
// TODO: Send using P2P protocol
|
||||
} else {
|
||||
let parameters: [String:Any] = [ "pubKey" : hexEncodedPublicKey ] // TODO: Figure out correct parameters
|
||||
return getTargetSnodes(for: hexEncodedPublicKey).mapValues { invoke(.sendMessage, on: $0, associatedWith: hexEncodedPublicKey, parameters: parameters) }.map { Set($0) }
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Public API (Obj-C)
|
||||
@objc public static func objc_sendSignalMessage(_ signalMessage: SignalMessage, to destination: String, with timestamp: UInt64) -> AnyPromise {
|
||||
let promise = sendSignalMessage(signalMessage, to: destination, timestamp: timestamp).mapValues { AnyPromise.from($0) }.map { Set($0) }
|
||||
|
@ -82,13 +72,22 @@ import PromiseKit
|
|||
}
|
||||
}
|
||||
|
||||
// If we have the p2p details then send message to that
|
||||
// If we have the p2p details and we have marked the user as online OR we are pinging the user, then use peer to peer
|
||||
// If that failes then fallback to storage server
|
||||
// TODO: probably only send to p2p if user is online or we are pinging them
|
||||
// p2pDetails && (isPing || peerIsOnline)
|
||||
if let p2pDetails = contactP2PDetails[destination] {
|
||||
if let p2pDetails = contactP2PDetails[destination], message.isPing || p2pDetails.isOnline {
|
||||
let targets = Promise.wrap([p2pDetails.target])
|
||||
return sendMessage(message, targets: targets).recover { _ in return sendThroughStorageServer() }
|
||||
return sendMessage(message, targets: targets).recover { error -> Promise<Set<Promise<RawResponse>>> in
|
||||
// The user is not online
|
||||
LokiAPI.setOnline(false, forContact: destination)
|
||||
|
||||
// If it was a ping then don't send to the storage server
|
||||
if (message.isPing) {
|
||||
Logger.warn("[Loki] Failed to ping \(destination) - Marking contact as offline.")
|
||||
throw error
|
||||
}
|
||||
|
||||
return sendThroughStorageServer()
|
||||
}
|
||||
}
|
||||
|
||||
return sendThroughStorageServer()
|
||||
|
|
|
@ -7,11 +7,13 @@ NS_SWIFT_NAME(LokiAddressMessage)
|
|||
@interface LKAddressMessage : LKEphemeralMessage
|
||||
|
||||
- (instancetype)initInThread:(nullable TSThread *)thread
|
||||
address:(NSString *)address
|
||||
port:(uint)port;
|
||||
address:(NSString *)address
|
||||
port:(uint)port
|
||||
isPing:(BOOL)isPing;
|
||||
|
||||
@property (nonatomic, readonly) NSString *address;
|
||||
@property (nonatomic, readonly) uint port;
|
||||
@property (nonatomic, readonly) BOOL isPing;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
@property (nonatomic) NSString *address;
|
||||
@property (nonatomic) uint port;
|
||||
@property (nonatomic) BOOL isPing;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -15,6 +16,7 @@
|
|||
- (instancetype)initInThread:(nullable TSThread *)thread
|
||||
address:(NSString *)address
|
||||
port:(uint)port
|
||||
isPing:(bool)isPing
|
||||
{
|
||||
self = [super initInThread:thread];
|
||||
if (!self) {
|
||||
|
@ -23,6 +25,7 @@
|
|||
|
||||
_address = address;
|
||||
_port = port;
|
||||
_isPing = isPing;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -437,7 +437,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
if (contentProto.lokiAddressMessage) {
|
||||
NSString *address = contentProto.lokiAddressMessage.ptpAddress;
|
||||
uint32_t port = contentProto.lokiAddressMessage.ptpPort;
|
||||
[LokiAPI didReceiveLokiAddressMessageForContact:envelope.source address:address port:port receivedThroughP2P:envelope.isPtpMessage]
|
||||
[LokiAPI didReceiveLokiAddressMessageForContact:envelope.source address:address port:port receivedThroughP2P:envelope.isPtpMessage];
|
||||
}
|
||||
|
||||
if (contentProto.syncMessage) {
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#import "TSSocketManager.h"
|
||||
#import "TSThread.h"
|
||||
#import "LKFriendRequestMessage.h"
|
||||
#import "LKAddressMessage.h"
|
||||
#import <AxolotlKit/AxolotlExceptions.h>
|
||||
#import <AxolotlKit/CipherMessage.h>
|
||||
#import <AxolotlKit/PreKeyBundle.h>
|
||||
|
@ -1792,7 +1793,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
isSilent:false
|
||||
isOnline:false
|
||||
registrationId:0
|
||||
ttl:message.ttl];
|
||||
ttl:message.ttl
|
||||
isPing:false];
|
||||
|
||||
NSError *error;
|
||||
NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error];
|
||||
|
@ -1879,6 +1881,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
|
||||
BOOL isSilent = message.isSilent;
|
||||
BOOL isOnline = message.isOnline;
|
||||
|
||||
LKAddressMessage *_Nullable addressMessage = [message as:[LKAddressMessage class]];
|
||||
BOOL isPing = addressMessage != nil && addressMessage.isPing;
|
||||
OWSMessageServiceParams *messageParams =
|
||||
[[OWSMessageServiceParams alloc] initWithType:messageType
|
||||
recipientId:recipientId
|
||||
|
@ -1887,7 +1892,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
isSilent:isSilent
|
||||
isOnline:isOnline
|
||||
registrationId:[cipher throws_remoteRegistrationId:transaction]
|
||||
ttl:message.ttl];
|
||||
ttl:message.ttl
|
||||
isPing:isPing];
|
||||
|
||||
NSError *error;
|
||||
NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error];
|
||||
|
|
|
@ -27,6 +27,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// Loki: Message ttl
|
||||
@property (nonatomic, readonly) uint ttl;
|
||||
|
||||
// Loki: Wether this message is a p2p ping
|
||||
@property (nonatomic, readonly) BOOL isPing;
|
||||
|
||||
- (instancetype)initWithType:(TSWhisperMessageType)type
|
||||
recipientId:(NSString *)destination
|
||||
device:(int)deviceId
|
||||
|
@ -34,7 +37,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
isSilent:(BOOL)isSilent
|
||||
isOnline:(BOOL)isOnline
|
||||
registrationId:(int)registrationId
|
||||
ttl:(uint)ttl;
|
||||
ttl:(uint)ttl
|
||||
isPing:(BOOL)isPing;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
isOnline:(BOOL)isOnline
|
||||
registrationId:(int)registrationId
|
||||
ttl:(uint)ttl
|
||||
isPing:(BOOL)isPing
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
@ -38,6 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
_silent = isSilent;
|
||||
_online = isOnline;
|
||||
_ttl = ttl;
|
||||
_isPing = isPing;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue