iOS客户端 Openfire服务 利用XEP-0065和XEP-0096 做out-of-band bytestream文件传输
Openfire服务可以做文件传输方法可供选择有:
- XEP-0047: in-band bytestreams:带内字节流传输协议 base64编码后放入iq消息,同普通文字消息,编解码需耗点资源效率一般,适用于较小文件;
- XEP-0096: SI File Transfer:文件传输流初始化协议
- 文档中提到可自行选择开发支持断点续传。当file元素包含range无素时,range包含offset、length两个属性,可以指出要传送的数据位于文件的什么位置。
- XEP-0065: SOCKS5 Bytestreams:带外socks5代理字节流传输协议
- 文档中提到 如果发送端位于公网,则接收端直接连接发送端拉取数据。如果双方都位于内网,则双方连接代理服务器,通过代理服务器转发数据。
- 两种应用场景原文:
- A direct connection in which the StreamHost is the Requester, as described under Direct Connection
- A mediated connection in which the StreamHost is a Proxy, as described under Mediated Connection
- XEP-0066: Out of Band Data:带外数据传输协议
- 具体看协议文档,没搞过;XEP-0096中提到XEP-0066的drawbacks,原文:
-
- It is not reliable.
- It does not work when one of the parties is behind a firewall.
- It provides limited metadata about files to be exchanged
- 还有一种,自建个文件服务器,发送方发送文件到文件服务器,上传成功后生成相应的缩略图(如果是图片文件的话)推送完成的消息给接收方,接收方收到消息后,去下载相应的文件,比较好理解,但我猜想每次比上述的方式多了次 磁盘IO;项目进度急得话,也是可以选用,可后续优化嘛。
我选的是XEP-0096和XEP-0065 :
XEP-0096对应的iOS版本文件 地址,XEP-0065 iOS 版本也可用上述地址的版本
初始化XMPPStream时需要注意:
XMPPJID *jid = [XMPPJID jidWithString:[NSString stringWithFormat:@"%@@%@", account, XMPPDomain]]; XMPPJID *jidWithResource = [jid jidWithNewResource:@"ios"]; [self.xmppStream setMyJID:jidWithResource];
普通JID格式如:account@domain (形如 hanmeimei@test)
第二行带上resource,不带我的程序报错:
<error code="503" type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error>
应该是两端的resource不一致
初始化XMPPSIFileTransfer相应代码:
NSString *sessionId = [_xmppStream generateUUID]; _sifiletransfer = [[XMPPSIFileTransfer alloc] init]; _sifiletransfer.sid = sessionId; [_sifiletransfer addDelegate:self delegateQueue:dispatch_get_main_queue()]; [_sifiletransfer activate:_xmppStream];
发送文件:
- (void)sendImageMessage:(NSData *)imageData toAccount:(NSString *)account{ XMPPJID *jid = [XMPPJID jidWithString:[NSString stringWithFormat:@"%@@%@/%@", account, XMPPDomain, [[_xmppStream myJID] resource]]]; [_sifiletransfer initiateFileTransferTo:jid withData:imageData]; }
其中文件接收方的JID完整格式:account@domain/resource (形如 hanmeimei@test/ios)
发送完成后在XMPPSIFileTransfer.h中的
@protocol XMPPSIFileTransferDelegate <NSObject> @required - (void)receivedImage:(NSData*)image from:(XMPPJID*)from; @end
可在你自己的文件中实现该方法接受文件
至此,我在内网可以通过此方式传输文件,Mac下得openfire服务,可选用源码或dmg方式 均可;
后来测试一端内网,一端外网出现错误,提示为:
<error code="404" type="cancel"><item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error>
openfire后台配置:
注意xmpp.proxy.externalip 填写你测试服务器的外网地址
路由器的7777端口也要映射到外网,如图:
至此,内外网两端发送文件测试也通过。
希望能帮到您。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。