【问题标题】:xmpp - send/receive file using turnsocket in iosxmpp - 在 ios 中使用 turnsocket 发送/接收文件
【发布时间】:2014-06-24 09:38:14
【问题描述】:

我正在开发聊天应用程序。现在我想使用 TurnSocket 类发送文件,但套接字无法连接。

- (void)sendToOtherDevice:(NSData *)fileData receiverJid:(NSString *)receiverJid {

    XMPPJID *JID = [XMPPJID jidWithString:[NSString stringWithFormat:@"%@/%@",receiverJid,resourceID]];

    NSLog(@"%@",[JID full]);

    NSLog(@"Attempting TURN connection to %@", JID);

    [TURNSocket setProxyCandidates:[NSArray arrayWithObjects:JID.domain, nil]];
    TURNSocket *turnSocket = [[TURNSocket alloc] initWithStream:[self xmppStream] toJID:JID];
    [turnSockets addObject:turnSocket];
    [turnSocket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
}

TurnSocket 委托方法

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

    NSLog(@"TURN Connection succeeded!");
    NSLog(@"You now have a socket that you can use to send/receive data to/from the other person.");

    [turnSockets removeObject:sender];
}

- (void)turnSocketDidFail:(TURNSocket *)sender {

    NSLog(@"TURN Connection failed!");
    [turnSockets removeObject:sender];

}

日志:

发送:

<iq type="get" to="meinantrieb.net" id="C6CF8EEE-B74E-45C8-8881-89BD0835056E">
<query xmlns="http://jabber.org/protocol/disco#items"/></iq>

RECV:

<iq xmlns="jabber:client" from="meinantrieb.net" to="kirit@meinantrieb.net/267698820914007696033596" id="C6CF8EEE-B74E-45C8-8881-89BD0835056E" type="result">
<query xmlns="http://jabber.org/protocol/disco#items">
<item jid="conference.meinantrieb.net"/>
<item jid="irc.meinantrieb.net"/>
<item jid="proxy.meinantrieb.net"/>
<item jid="pubsub.meinantrieb.net"/>
<item jid="vjud.meinantrieb.net"/></query></iq>

发送:

<iq type="get" to="proxy.meinantrieb.net" id="22D98197-F1F2-4D8F-AA9C-E1076D0EF9F7">
<query xmlns="http://jabber.org/protocol/disco#info"/></iq>

RECV:

<iq xmlns="jabber:client" from="proxy.meinantrieb.net" to="kirit@meinantrieb.net/267698820914007696033596" id="22D98197-F1F2-4D8F-AA9C-E1076D0EF9F7" type="result">
<query xmlns="http://jabber.org/protocol/disco#info">
<identity category="proxy" type="bytestreams" name="SOCKS5 Bytestreams"/>
<feature var="http://jabber.org/protocol/disco#info"/>
<feature var="vcard-temp"/>
<feature var="http://jabber.org/protocol/bytestreams"/>
<x xmlns="jabber:x:data" type="result">
<field var="FORM_TYPE" type="hidden">
<value>http://jabber.org/network/serverinfo</value></field></x></query></iq>

发送:

<iq type="get" to="proxy.meinantrieb.net" id="84AFA217-7F71-48B4-B56C-66995FE20490">
<query xmlns="http://jabber.org/protocol/bytestreams"/></iq>

RECV:

<iq xmlns="jabber:client" from="proxy.meinantrieb.net" to="kirit@meinantrieb.net/267698820914007696033596" id="84AFA217-7F71-48B4-B56C-66995FE20490" type="result">
<query xmlns="http://jabber.org/protocol/bytestreams">
<streamhost jid="proxy.meinantrieb.net" host="0.0.0.0" port="7777"/></query></iq>

发送:

<iq type="set" to="vote@meinantrieb.net/(null)" id="694B5F07-3A70-4556-9268-1D47AC251229">
<si xmlns="http://jabber.org/protocol/si" id="694B5F07-3A70-4556-9268-1D47AC251229" profile="http://jabber.org/protocol/si/profile/file-transfer">
<file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="abc.txt" size="2239350"/>
<feature xmlns="http://jabber.org/protocol/feature-neg">
<x xmlns="jabber:x:data" type="form">
<field var="stream-method" type="list-single"><option><value>http://jabber.org/protocol/bytestreams</value></option><option><value>http://jabber.org/protocol/ibb</value></option></field></x></feature></si></iq>

RECV:

<iq xmlns="jabber:client" from="vote@meinantrieb.net/(null)" to="kirit@meinantrieb.net/267698820914007696033596" type="result" id="694B5F07-3A70-4556-9268-1D47AC251229">
<si xmlns="http://jabber.org/protocol/si">
<feature xmlns="http://jabber.org/protocol/feature-neg">
<x xmlns="jabber:x:data" type="submit">
<field var="stream-method"><value>http://jabber.org/protocol/bytestreams</value></field></x></feature></si></iq>

发送:

<iq type="set" to="vote@meinantrieb.net/(null)" id="694B5F07-3A70-4556-9268-1D47AC251229"><query xmlns="http://jabber.org/protocol/bytestreams" sid="694B5F07-3A70-4556-9268-1D47AC251229" mode="tcp">
<streamhost xmlns="http://jabber.org/protocol/bytestreams" jid="proxy.meinantrieb.net" host="0.0.0.0" port="7777"/></query></iq>

RECV:

<iq xmlns="jabber:client" from="vote@meinantrieb.net/(null)" to="kirit@meinantrieb.net/267698820914007696033596" type="error" id="694B5F07-3A70-4556-9268-1D47AC251229">
<error code="404" type="cancel">
<item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>

TURN 连接失败!

任何帮助或建议将不胜感激。

【问题讨论】:

  • socks 代理是否在 7777 端口上响应?
  • 您使用的是什么 xmpp 服务器?也许您必须在其一侧激活一些模块以充当 socks 代理,例如在 ejabberd 上:ejabberd.im/node/9033
  • @VincentG 如何在 ejabberd 上测试代理服务器。
  • 只需尝试类似 telnet localhost 7777 来查看是否连接或 lsof/netstat 来查找开放端口
  • 这可能会有所帮助,这是发送 404 的 ejabberd 部分:github.com/processone/ejabberd/blob/master/src/…

标签: ios xmppframework


【解决方案1】:

在通过 xmppStream 使用 turnsocket 发送 iq 时,请确保您使用正确的 jid 和 jid。

像这样。 至:arpan@fb.purologics.com/hsdvydvdv
来自:push@fb.purologics.com/ksjbdjdd '/' "hsdvydvdv" 和 "ksjbdjdd" 之后是资源 ID。在发送 iq 以建立正确连接时它是必需的。

您可以在 AppDelegate 的以下方法中获取往返的完整 jid :

- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
    DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [presence fromStr]);

  //  NSString *presenceType = [presence type]; // online/offline
    NSString *myUsername = [[sender myJID] user];
    NSString *presenceFromUser = [[presence from] user];

    NSLog(@" Printing full jid of user %@",[[sender myJID] full]);
    NSLog(@"Printing full jid of user %@",[[sender myJID] resource]);
    NSLog(@"From user %@",[[presence from] full]);
    senderFullID=[[presence from] full];



}

【讨论】:

    【解决方案2】:

    据我所知,最好专注于让两个 jabber 客户先交谈,因为在与其他客户沟通时存在很多问题。 (即 Adium、Spark)
    在两个 jabber 客户端之间建立连接现在正在工作。连接到 Adium 或 Spark 等其他 jabber 客户端确实存在一些问题。

    对于两个要连接的 jabber 客户端,一个必须是服务器(目标),一个必须是客户端(请求者)。

    因此,我们需要实现来自另一个客户端的传入请求。为此,我们需要几行代码来处理传入的 TURN 请求。

    - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
    {
        DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [iq elementID]);
    
        if ([TURNSocket isNewStartTURNRequest:iq]) {
            NSLog(@"IS NEW TURN request..");
            TURNSocket *turnSocket = [[TURNSocket alloc] initWithStream:[self xmppStream] incomingTURNRequest:iq];
            [turnSockets addObject:turnSocket];
            [turnSocket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
            [turnSocket release];
        }
    
        return YES;
    }
    

    如果您在两个 jabber 客户端上进行测试,您将能够从任一端建立连接。从 Spark 接收数据很好,但发送数据仍然出现 406 错误。 无法以任何方式与 Adium 通信。
    我的建议:

    1. 自行尝试使用专用服务器。 (我使用的是 Linode 的 VPS 主机)
    2. 从 primaryResource.jid 获取您的 jid

    【讨论】:

    • 是的。我还为传入请求添加了代码。当我将文件从一个客户端发送到另一个客户端时,if([TURNSocket isNewStartTURNRequest:iq]) 对两个客户端都是正确的。
    猜你喜欢
    • 2011-09-13
    • 2012-01-13
    • 1970-01-01
    • 2012-02-11
    • 2014-04-16
    • 1970-01-01
    • 2019-03-21
    • 2015-08-07
    • 2012-08-19
    相关资源
    最近更新 更多