123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /**
- * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
- #import "WSMessage.h"
- #import "NextcloudTalk-Swift.h"
- static NSTimeInterval kSendMessageTimeoutInterval = 15;
- @interface WSMessage ()
- @property NSTimer *timeoutTimer;
- @property NSURLSessionWebSocketTask *webSocketTask;
- @end
- @implementation WSMessage
- - (instancetype)initWithMessage:(NSDictionary *)message
- {
- self = [super init];
- if (self) {
- self.message = message;
- }
- return self;
- }
- - (instancetype)initWithMessage:(NSDictionary *)message withCompletionBlock:(SendMessageCompletionBlock)block
- {
- self = [self initWithMessage:message];
- if (self) {
- self.completionBlock = block;
- }
- return self;
- }
- - (void)setMessageId:(NSString *)messageId
- {
- _messageId = messageId;
- NSMutableDictionary *newMessageDict = [[NSMutableDictionary alloc] initWithDictionary:_message];
- [newMessageDict setObject:messageId forKey:@"id"];
- _message = newMessageDict;
- }
- - (BOOL)isHelloMessage
- {
- if ([[_message objectForKey:@"type"] isEqualToString:@"hello"]) {
- return YES;
- }
- return NO;
- }
- - (BOOL)isJoinMessage
- {
- if ([[_message objectForKey:@"type"] isEqualToString:@"room"]) {
- return YES;
- }
- return NO;
- }
- - (void)setMessageTimeout
- {
- // NSTimer uses the runloop of the current thread. Only the main thread guarantees a runloop, so make sure we dispatch it to main!
- // This is mainly a problem for the "hello message", because it's send from a NSURL delegate and the timer sometimes fails to run
- dispatch_async(dispatch_get_main_queue(), ^{
- self->_timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:kSendMessageTimeoutInterval target:self selector:@selector(executeCompletionBlockWithSocketError) userInfo:nil repeats:NO];
- });
- }
- - (void)ignoreCompletionBlock
- {
- dispatch_async(dispatch_get_main_queue(), ^{
- self.completionBlock = nil;
- [self->_timeoutTimer invalidate];
- });
- }
- - (void)executeCompletionBlockWithStatus:(NCExternalSignalingSendMessageStatus)status
- {
- // As the timer was create on the main thread, it needs to be invalidated on the main thread as well
- dispatch_async(dispatch_get_main_queue(), ^{
- if (self.completionBlock) {
- self.completionBlock(self.webSocketTask, status);
- self.completionBlock = nil;
- [self->_timeoutTimer invalidate];
- }
- });
- }
- - (void)executeCompletionBlockWithSocketError
- {
- [self executeCompletionBlockWithStatus:SendMessageSocketError];
- }
- - (NSString *)webSocketMessage
- {
- NSError *error;
- NSString *jsonString = nil;
- NSData *jsonData = [NSJSONSerialization dataWithJSONObject:_message
- options:0
- error:&error];
- if (!jsonData) {
- NSLog(@"Error creating websocket message: %@", error);
- } else {
- jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
- }
- return jsonString;
- }
- - (void)sendMessageWithWebSocket:(NSURLSessionWebSocketTask *)webSocketTask
- {
- self.webSocketTask = webSocketTask;
- if (self.completionBlock) {
- [self setMessageTimeout];
- }
- //NSLog(@"Sending: %@", self.webSocketMessage);
- NSURLSessionWebSocketMessage *message = [[NSURLSessionWebSocketMessage alloc] initWithString:self.webSocketMessage];
- [webSocketTask sendMessage:message completionHandler:^(NSError * _Nullable error) {
- if (error && self.completionBlock) {
- [self executeCompletionBlockWithSocketError];
- }
- }];
- }
- @end
|