请教一个关于在 NSURLConnection 使用 NSInputStream 的问题

2014-04-19 13:42:32 +08:00
 NUT
因为项目需求,我需要建立一个Connection连接,上层类通过该连接不断向服务器发送buffer。因为连接数限制,不能使用socket,要求采用http。目前我使用NSMutableURLRequest 中setHTTPBodyStream 的方法。

我现在的代码思路是在
1.初始化一个NSInputStream,然后设置代理并且加入runloop
2.在Request把InputStream 加进去。
3.建立连接。
4.等待NSInputStream的回调方法,然后加入数据。

代码
NSMutableData *mutableData = [NSMutableData dataWithLength:uploadData.length];
self.inputStream = [NSInputStream inputStreamWithData:mutableData];
self.inputStream.delegate =self;
[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.inputStream open];
[request setHTTPBodyStream:self.inputStream];

NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];

// delegate
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
switch (eventCode) {
case NSStreamEventOpenCompleted: {
NSLog(@"producer stream opened");
} break;
case NSStreamEventHasBytesAvailable: {
// 这里写入buffer
NSLog(@"NSStreamEventHasBytesAvailable");
}
}

现在的问题:
1.初始化流时,发送Stream的大小是否为初始化传入Data的大小?
NSMutableData *mutableData = [NSMutableData dataWithLength:uploadData.length];
self.inputStream = [NSInputStream inputStreamWithData:mutableData];
2.我打印日志发现connection是在流写入完成之后然后才建立连接发送数据的。能否做到先建立Connection然后自己主动调用Stream同步方法往里面写数据,这时候已经开始传入数据了(现在使用的是stream的回调方法)?

这里先谢谢各位大牛。:D
4348 次点击
所在节点    iDev
10 条回复
alexrezit
2014-04-19 13:55:59 +08:00
用 AFNetworking 吧...
NUT
2014-04-19 14:01:40 +08:00
@alexrezit 公司不让用第三方库......
alexrezit
2014-04-19 14:15:58 +08:00
@NUT
辭職.
NUT
2014-04-19 15:54:39 +08:00
@alexrezit 我勒个大擦...这是解决问题的根本啊! 不过刚回西安还是先稳稳再说。
BB9z
2014-04-20 22:49:22 +08:00
但 copy 一个 1.x 的 AFURLConnectionOperation 吧。
NUT
2014-04-23 21:01:31 +08:00
@BB9z 我最后实现了,用底层的c接口。
MartinTsao
2014-05-03 23:14:33 +08:00
@NUT
你好,我现在也遇到此类问题,我需要做到的是边下载边上传.
对于CFStreamCreatePairWithSocket的使用我没有摸清思路,请问能帮助一下我吗?
NUT
2014-05-22 15:48:45 +08:00
@MartinTsao
边下载边上传。你还是建立2条连接比较好。也就是一个是上行,一个下行。
我这边测试的结果,NSURLConnection 只有把数据上传完以后才会给你返回response。

CFStreamCreatePairWithSocket 你可以看看 苹果官方示例, SimpleURLConnections 的PostController.m 文件。 你外层向流写入数据的时候,可以不用等他回调,可以直接写。
alison123456
2015-05-21 17:41:31 +08:00
你好,我遇到相同问题。看了官方例子的代码,对于CFStreamCreatePairWithSocket 用法不太理解,例子中实现了NSoutputStream的委托,而没有对NSInputStream继续读入要发送的buffer。楼主是采用的官方例子中方法解决问题的吗?能不能指点一下,谢谢!
NUT
2015-05-22 08:59:52 +08:00
@alison123456

简单点说就是, CFStreamCreatePairWithSocket 关联一对stream (InputStreamOne ,OutputStreamOne),然后把 OutputStreamOne 的指针赋给 HTTPRequest 的 InputStream ,需要写数据就直接向 关联管道的InputStreamOne来写。因为代理方法是一样的 - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode ,所以根据 [ aStream isEqual:InputStreamOne]
来决定是否写入,需要注意的坑是 需要把这些 InputStreamOne OutputStreamOne 都加入runloop里面,如果发送完毕数据 必须手动关闭InputStreamOne,否则你永远不会上传完成。

另可以通过cfnetwork那层来实现,总体来比较简单,可以看看 webscoket ios 实现的代码。

希望对你有用。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/109193

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX