Чтение сложных сокетов
У меня есть вопрос о дизайне кода, я не могу придумать наиболее эффективный способ справиться с этим:
По сути, я хочу отправить JSON-запрос и прочитать ответ обратно с сервера за один раз.
У меня есть такие методы, как:
-(BOOL)sendString:(NSString *)sendString;
//This should return a NSString and a BOOL
-(NSDictionary *)loginRequestWithEmail:(NSString *)userEmail andPassword:(NSString *)userPassword;
//This should return a NSString and a BOOL
-(NSDictionary *)requestNewUserAccountWithDisplayName:(NSString *)displayName Email: (NSString *)userEmail andPassword:(NSString *)userPassword;
Я объясню что
-(BOOL)sendString:(NSString *)sendString;
делает, в основном отправляет JSON-строку на сервер и получает ответ о том, провалился он или нет.
Я знаю, как записать это на сервер и прочитать это. Проблема заключается в том, чтобы сделать это вместе, поэтому я могу вернуть это значение BOOL как true или false, чтобы посмотреть, сработало ли оно.
Теперь после записи в сокет я получаю ответ и должен прочитать его с помощью метода делегата:
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
Который вызывается, как только сервер дает ответ. Проблема в том, что все это чтение / запись в сокет происходит асинхронно.
Так как это происходит, я не могу иметь метод, который делает это:
-(BOOL)sendString:(NSString *)sendString{
NSError *error;
NSLog(@"Sending String: %@",sendString);
NSDictionary *blobData = [NSDictionary dictionaryWithObjectsAndKeys:
sendString,@"string",
nil];
NSString *blobString = [[NSString alloc]
initWithData:[NSJSONSerialization dataWithJSONObject:blobData options:kNilOptions error:&error]
encoding:NSUTF8StringEncoding];
NSLog(@"Blob Created: %@", blobString);
NSDictionary *requestData = [NSDictionary dictionaryWithObjectsAndKeys:
@"send_string",@"request_type",
[NSNumber numberWithInt:0],@"security_level",
@"ios",@"device_type",
//No Email Provided, This is just for testing
blobString,@"blob",
nil];
NSData *JSONRequestData = NULL;
JSONRequestData = [NSJSONSerialization dataWithJSONObject:requestData options:kNilOptions error:&error];
NSLog(@"Contents of JSONRequestData: %@",[[NSString alloc] initWithData:JSONRequestData encoding:NSUTF8StringEncoding]);
JSONRequestData = [[[[NSString alloc] initWithData:JSONRequestData encoding:NSUTF8StringEncoding] stringByAppendingString:@"\\n"] dataUsingEncoding:NSUTF8StringEncoding];
//Write the data
NSMutableData *JSONRequestDataWithLineEnding = [[NSMutableData alloc] initWithData:JSONRequestData];
[JSONRequestDataWithLineEnding appendData:[GCDAsyncSocket CRLFData]];
[asyncSocket writeData:JSONRequestDataWithLineEnding withTimeout:-1 tag:1];
//read a response
[asyncSocket readDataWithTimeout:-1 tag:2];
//This should be done in the didRead delegate
NSString *failure = [serverJSONResponseParsed objectForKey:@"failure"];
NSLog(@"Contents of string failure: %@", failure);
if ([failure isEqualToString:@"none"]) {
NSLog(@"Success Sending String");
return TRUE;
}
else {
NSLog(@"Failure: %@",failure);
return FALSE;
}
}
Поскольку код, который вызывается после
[asyncSocket readDataWithTimeout:-1 tag:2];
выполняется до того, как данные прочитаны (потому что это все асинхронно).
Я понимаю, что должен сделать что-то в этом методе делегата. Это нормально, но у меня есть разные типы ответов, и каждый ответ должен обрабатываться по-разному.
Моя идея: пометить каждую из команд записи, а затем использовать некоторые
if(this_tag) {do this} ....else if(that_tag) {do this} ....
в методе делегата didReadData.
Но как мне вернуть эти данные правильно? Иногда мне нужно вернуть BOOL, иногда мне нужно вернуть NSDictionary, NSString и т. Д.
Мне бы хотелось, чтобы каждый из моих методов запроса, указанных выше, возвращал связанные с ними данные, но не могу (по крайней мере, неэффективно). Должен ли я сделать два разных метода для каждого запроса?
т.е.
sendString
getSendStringResponse
Я немного озадачен тем, как справиться с этим.
Прошу прощения, если мне неясно,
Я ценю любую помощь, которую я могу получить.
1 ответ
Что я хотел бы сделать, это создать какой-то тип протоколов для этого конкретного приложения. Например, допустим, у вас есть следующие типы данных (не относящиеся к Obj-C) dat1, dat2, dat3 и т. Д., Которые необходимо отправить этому приложению и получить соответствующий ответ в виде res1, res2, res3 и т. Д. с подписью для каждого типа данных для отправляющей части, а также для отвечающей части. Перед отправкой каждой информации вам необходимо поставить перед ней подпись. На стороне получателя, используя readDataWithTimeout, в методе обратного вызова didReadData извлеките заголовок для полученных данных и определите ответ на основе протоколов, которые вы согласовали / разработали ранее. Есть другие дополнительные шаги, прежде чем это завершить дизайн. Например, как часть информации вашего заголовка, она может содержать другую информацию, такую как длина данных и т. Д. Надеюсь, это поможет вам начать работу.