在iPhone SDK中发送/接收XMPP文件...?

3

如何使用xmpp框架在iphone sdk中发送/接收文件? 目前我正在使用XEP-0065类,并使用以下代码:

ObjTURNSocket = [[TURNSocket alloc] initWithStream:((TestAppDelegate*)[[UIApplication sharedApplication] delegate]).xmppStream 
                                                 toJID:chatuser.jid];
    [ObjTURNSocket start:self];

我从服务器收到以下响应:

<iq type="error" id="AB2ED567-B97F-4DFE-B789-7731A617C239" to="kapil@testweb/6df6dc96" from="jabber.org">
   <query xmlns="http://jabber.org/protocol/disco#items"/>
   <error code="404" type="cancel">
      <remote-server-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
   </error>
 </iq>`

任何帮助或建议都将受到高度赞赏。

我正在寻找一个关于使用XEP-0065扩展类-TURNSocket.h和TURNSocket.m在XMPP中发送/接收文件的教程。 - Matrix
你正在使用哪个版本的XMPPFramework?当前版本使用startWithDelegate:而不是start:。另外,chatuser.jid的值是多少? - Joe Hildebrand
在我的类中还有一个名为startWithDelegate的方法,但你能给我一个想法,在TURNSocket类中哪里传递文件内容。 - Matrix
3个回答

4

首先,使用可能用于代理的服务器数组调用 setProxyCandidates 方法。默认设置为“jabber.org”,由于您的服务器未与 jabber.org 进行联合,因此会返回发现错误。

接下来,在您的代理中实现以下方法:

- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket;
- (void)turnSocketDidFail:(TURNSocket *)sender;

接下来,在你的didSucceed实现中,使用传入的socket发送数据,方法如下:

- (void)writeData:(NSData *)data 
      withTimeout:(NSTimeInterval)timeout 
              tag:(long)tag;

最后,关闭套接字:

- (void)disconnectAfterWriting;

我通过查看TURNSocket.m的源代码,查找硬编码的“jabber.org”,然后搜索[delegate来查找调用委托的地方,从而解决了这个问题。这使我回到了TURNSocket.h,其中记录了委托需要实现的协议。

如果我不想使用代理,也没有使用任何代理服务器怎么办?如果我传递 [setProxyCandidates:nil],那么 turnSocketDidFail 就会被调用...!即使我尝试传递服务器 IP,turnSocketDidFail 方法仍然会被调用。那么现在我应该在 "SetProxyCandidates" 中传递什么? - Matrix
1
RECV: <iq type="error" id="D9305C67-5713-4804-BA8E-863EA8B2AAEE" from="shiv@triforceweb" to="kapil@triforceweb/594a81f"><query xmlns="http://jabber.org/protocol/bytestreams" sid="D9305C67-5713-4804-BA8E-863EA8B2AAEE" mode="tcp"><streamhost jid="proxy.triforceweb" host="192.168.1.11" port="7777"/></query><error code="503" type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq> - Matrix
如果您不想进行代理,那么您应该使用其他代码。您可以使用XEP-47,但它的可扩展性不好。如果您在同一网络上,您可以设置一个一次性Web服务器,并将HTTP URL传递到另一侧。 - Joe Hildebrand
谢谢Joe,感谢您的回复。 我在考虑另一种方式,例如:假设用户(A)想将文件发送给用户(B),那么用户(A)将该文件上传到服务器,并从服务器响应中获取已上传文件的URL。现在,用户(A)向用户(B)发送自定义消息类型“FILE_TRANSFER”,其中包含已上传文件的URL(带名称)。当用户(B)收到类型为“FILE_TRANSFER”的自定义消息时,他/她有三个选项,可以接受、拒绝或不做任何操作。 - Matrix
1
@Iducool,您需要在“to”字段中发送“jabberID@domain/resource”,这样服务器才能识别 Jabber 服务器上的用户并初始化文件传输。 - Rohit Pathak
显示剩余4条评论

1

我最终不得不自定义TURNSocket类以满足我的特定需求,从而能够将文件从我的iOS设备传输到另一个设备。如果有代理服务器可用,则TURNSocket类可能适合某人的需求。但是,如果这是直接连接,其中可能没有可用的代理服务器,则需要进行一些额外的工作,以设置您的设备以能够连接到另一个设备并直接传输文件。

在其当前形式下,我能够使用TURNSocket接收文件,只需进行一次轻微修改即可。由于代码当前的状态,id和sid被分配相同的值,无法保证接收到的数据包将具有相同的唯一标识符值,既id又sid。


edenwaith,你能分享一下你是如何使用TurnSocket传输文件的吗?我一直收到“socket did fail”的错误提示。 - Karun
@edenwaith,您能否分享一下您如何使用TurnSocket传输文件的方法?我一直收到“套接字失败”的错误信息。 - nr5
抱歉,我不再拥有原始代码的访问权限,因此无法分享任何内容。 - edenwaith

0

你应该使用xep-96来实现文件的共享和接收。 之后,只需使用相关数据启动xmppSifiletranfer。

-(void)sendToOtherDevice:(NSData *)fileData receiverJid:(XmPPJId *)senderFullID file:(NSString *)fileName{

            myFileTransferID=[xmppStream generateUUID];
            XMPPJID *jid =senderFullID;
            sifiletransfer=[[XMPPSIFileTransfer alloc]init];
            [sifiletransfer initiateFileTransferTo:jid withData:fileData file:fileName passedsid:myFileTransferID];

            if ([jid.domain isEqualToString:[xmppStream myJID].domain]) {
                [TURNSocket setProxyCandidates:[NSArray arrayWithObjects:jid.domain, nil]];
            } else {
                [TURNSocket setProxyCandidates:[NSArray arrayWithObjects:jid.domain,[xmppStream myJID].domain, nil]];
            }
             TURNSocket *socket = [[TURNSocket alloc] initWithStream:xmppStream toJID:jid sid:myFileTransferID];
           // [socket setDataToSend:fileData];

            [socket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    # delegater of turnsocket
    - (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket
    {
        NSLog(@"Socket Suceeed Port For File Transfer: %d",socket.localPort);
        DDLogInfo(@"TURN Connection succeeded!");
        DDLogInfo(@"You now have a socket that you can use to send/receive data to/from the other person.");
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Hurray!!"
         message:@"Conection Established"
         delegate:nil
         cancelButtonTitle:@"Ok"
         otherButtonTitles:nil];
         [alertView show];
    }

if you guys have any other issue regarding file transfer comment below.I will surely help you.

我遇到了以下错误<iq xmlns="jabber:client" type="error" id="797190C9-89F8-4D15-8DF6-90B8C4CE40AF" from="abc@192.168.2.120" to="def@192.168.2.120/173bf5c2"><query xmlns="http://jabber.org/protocol/bytestreams" sid="797190C9-89F8-4D15-8DF6-90B8C4CE40AF" mode="tcp"><streamhost jid="proxy.192.168.2.120" host="192.168.2.120" port="7777"/></query><error code="503" type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>。请问能帮助我解决这个问题吗?可能是什么原因导致的呢? - Jayeshkumar Sojitra
看起来你缺少了一些段落,你是否正确配置了 XMPPSIFileTransfer 文件? - Arpan Dixit
我不确定XMPPSIFileTransfer文件的配置。你能告诉我XMPPSIFileTransfer文件需要哪些配置吗?我已经设置了xmpp.proxy.externalip,它是我的Openfire服务器的域名,这样可以吗? - Jayeshkumar Sojitra
你的XMPP包中有XEP-96文件夹吗?如果有,只需打开它,你会找到XMPPSIFileTranfer文件。然后查看在其中声明的委托方法。 - Arpan Dixit
我的应用程序中xep-96文件夹中有XMPPSIFileTranfer文件。我已经在我的AppDelegate中实现了委托方法。你能否请看一下我的问题:http://stackoverflow.com/questions/26250533/service-unavailable-503-error-for-file-transfer-in-xmpp-with-ios 这将非常有帮助。我已经卡了两天了。:( - Jayeshkumar Sojitra
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接