jdev - 2021-07-02

  1. 512bit

    What are the typical transfer speeds achieved during a jingle file transfer?

  2. jonas’

    512bit, whatever the link between the two clients can achieve

  3. jonas’

    there is no "typical" number there

  4. jonas’

    depends on the negotiated transfer method

  5. Sam

    Okay, trying again to phrase a problem that's been bugging me, maybe someone here will have insights. I'm building a MUC library and it's showing me the weaknesses in my core XMPP library. One is that I have no way to track stanza errors (other than IQs). When I send a join presence for the MUC for instance, I always expect a response so I block until receivnig it, something like muc.Join(timeout, jid) roomOrError. This works for the self-presence because the MUC handler is tracking all presence payloads that have the <x xmlns="muc#user"/> or whatever in them so it can associate the response and hand it back. It can't hand back an error though because that is not a MUC specific payload and it doesn't know about it.

  6. Sam

    So instead I thought about having a general xmpp.SendPresence(timeout, presence) error that will block until it gets a presence error. I can call that from within muc.Join to send the presence, then if the success response happens I can cancel the timeout (don't worry about that, just realize that timeouts can be canceled early) and return it, otherwise we wait for the error until the timeout is hit and then return an error if no error or success was received.

  7. Sam

    However, this feels wrong. Using xmpp.SendPresence or whatever the *expected* behavior will be that it times out and returns that it timed out 90% of the time (since we hopefully don't get presence errors often). It works for the MUC case, but for genreally using it it feels weird.

  8. Sam

    Has anyone else run into something like this?

  9. MattJ

    I think the summary of what you're trying to say is that in some cases in XMPP there is no explicit success response

  10. MattJ

    Which is indeed the case

  11. Kev

    I have generally found that I don’t need stateful errors for very much outside iqs.

  12. MattJ

    Yet any stanza can trigger an error, that you would want to handle

  13. Sam

    Heh, yes, I suppose that's all I was saying with all of that. It makes it hard to track errors because the timeout is indeterminant (sp?).

  14. Zash


  15. Sam

    Normally it's not a problem for that reason, but MUCs it can be since I want to block until the join was successful or an error is received (or the timeout is hit). It makes more sense to have the timeout only if there is an error and a success case

  16. Kev

    You can always* use ids for tracking errors to particular stanzas if you care.

  17. MattJ

    I think the answer is partly as Kev says - the stanzas without an explicit success /usually/ don't need one for practical use-cases

  18. Sam

    Kev: yah, that's what we're talking about

  19. Kev

    When you say block, I assume you mean that a MUC join is happening in its own coroutine that you’re blocking, not that you’re blocking the calling site?

  20. Zash

    I've thought about this too. Not sure I'd want anything blocking, but some way to race a timer came to mind.

  21. Sam

    Yes, sorry blocking a coroutine.

  22. Kev

    (Since MUC joins you generally want to be async and to continue processing other data while you wait for them)

  23. Sam

    Blocking is the normal and expected behavior for things like this; the user can always await it if they want it in the background (more or less)

  24. Kev


  25. Kev

    Blocking the join, not blocking the caller.

  26. Sam

    The issue is more or less that if I've registered a "muc" handler the success case gets picked up (it's a MUC specific payload), the error case doesn't (unless I want the MUC handler to handle *all* error presences)

  27. Kev

    I’m missing why it’s hard to timer this (probably my fault).

  28. Sam

    The timer isn't the issue, that part is fine

  29. Sam

    Sorry, I've been struggling to explain this; not your fault.

  30. Zash

    It's even more fun. The true completion signal is the subject message 🙂

  31. Zash

    For a MUC join at least.

  32. Kev

    What we do in Swift is we start a timer on join. If we succeed the timer’s cancelled. If it doesn’t succeed and the timer fires the user is warned that the join probably won’t complete - but you could easily hard fail instead.

  33. Sam

    hmm, good point, I was taking the completion message to be the self-presence.

  34. Zash

    A way to have composable completion events might be nice.

  35. Kev

    Zash: Ah. It’s the subject message…or the first non-history message because some servers don’t send a subject. Although that was an old ejabberd bug, and it’s probably been fixed for a decade.

  36. Sam

    Kev: that's what we do as well. I'd also like it to be able to return the presence error (if any) though.

  37. Zash

    Then you could take a message and a timer, or a message and a thing that watches for a message receipt, or a presence and a thing that watches for the subject.

  38. Kev

    Sam: But that’s easy enough, isn’t it? If you get a presence error reply to your join stanza, you have the error.

  39. Sam

    Kev: right, but this is a MUC handler that receivese MUC paylods. The presence error is a normal generic one, not a MUC specific thing. So I'd have to listen for *all* presences in the MMUC handler to do that. This isn't actually how my library works right now, and it seems like there is a better way.

  40. jonas’

    Sam, make a thing which allows you to listen to presences with a specific ID

  41. Kev

    I would personally just listen to all presences, and check the id. Or have a ‘tell me if this id comes in’ handler.

  42. Sam

    Right, so like I said in the orignial post if I do that it works okay for MUCs, but then if the user uses it the API feels weird:

  43. jonas’

    then it’s tied semantically to the MUC by the ID and it’s less ugly

  44. Kev

    But I would very very much not make sending presence into a thing with a reply handler, because 99% of the time that’s just pointless.

  45. Sam

    xmpp.SendPresence(timeout, presence) error or whatever. The expected case is that the timeout is triggered momst of the time. Feels weird.

  46. Kev

    Yes. That is what I would not do.

  47. Sam

    Right, what Kev said

  48. jonas’

    Sam, how about xmpp.WaitPresenceError(timeout, id)?

  49. Sam

    Works great for MUC, not great for 90% of other cases :)

  50. Sam

    jonas’: yah, that's what I was saying (more or less)

  51. jonas’

    and keep xmpp.SendPresence fire-and-forget naive

  52. Kev

    But why not make xmpp.SendPresence(presence, optionalHandler, optionalTimer)?

  53. Kev

    Off for lunch :)

  54. Zash

    Kev, it may have been Prosody (too) which didn't used to send a subject if the subject was empty/unset. Fixed now anyways.

  55. Sam

    That's what I've done right now (ish). There's Send for sending any general stanza in a fire-and-forget way, SendPresence for sending a presence specifically and waiting for an error (or timnig out).

  56. Sam

    And a bunch of other sort of related things that don't matter.

  57. Sam

    Anyways, maybe this is the only way with how I have this structured (or give the MUC thing access to all presences and what not, but that feels wrong) and the answer is "Okay, SendPresence is weird, don't use it most of the time"

  58. Sam

    Thanks for the brainstorming.

  59. jonas’

    fwiw, it seems that aioxmpp does not track presence errors during muc join based on the ID but on the from

  60. Sam

    I thought about adding a way to track based on from so that any errors from a specific thing get forwarded to the MUC handler but that requires being able to modify the handler at runtime (eg. when we join a room, add "chat.myserver.com" to the valid from) which bothers me a bit, and also means that every separate plugin has to do its own id (or from) tracking internally to match responses with requests instead of the main XMPP handler thing just doing it for everything

  61. Sam

    But maybe that would be better than adding weird SendPresence functions that are expected to fail

  62. Sam

    (or timeout, rather)

  63. Sam

    Hmm, now the subject thing is bothering me a bit. Does it matter if they can do things before the message history is sent, or should I block until the subject is set? I can't tell that it would matter, you might just send a message before getting context back, which feels weird but isn't the end of the world. Also I'm kind of assuming a MUC-MAM future anyways, so I dunno if I care about history/subject as much.

  64. Kev

    > fwiw, it seems that aioxmpp does not track presence errors during muc join based on the ID but on the from Pretty sure that’s what we did in Swiften, without checking.

  65. jonas’

    Sam, aioxmpp doesn’t prevent you from doing things before the subject was received. It only uses it as a marker for when to start trusting nickname<->jid relationships because it has up-to-date presence or somesuch (I’d have to look it up).

  66. Sam

    Makes sense; for now I'll probably consider join successful on self-presence then. We'll see if I use subject for anything later (so far I haven't even looked at that and am not tracking the subject at all)

  67. Zash

    It would be weird for the join to fail between self-presence and subject.

  68. Sam

    As far as I can tell from the spec it can't, you're actually done once you get self-presence. Subject is just something that might or might not show up later.

  69. Kev

    Zash: What if the server has to hit storage to fetch the subject, but not the members? That *might* mean a noticable delay between them.

  70. Sam

    (it's a SHOULD, so it probably will, but I don't see anything that relies on it)

  71. Kev

    But ultimately a network can fail at any point.

  72. Zash

    True. The whole thing could crash at any moment!

  73. Kev

    Sam: What relies on it is it’s what implementations use for knowing the join’s complete :)

  74. Zash

    Sam, hm? I thought sending subject was mandatory

  75. Kev

    SHOULD doesn’t mean OPTIONAL, it means “Things might break if you don’t do this, so be sure you know what you’re doing” ;)

  76. Sam

    Kev: why rely on that instead of getting self-presence?

  77. Kev

    Sam: Because presence comes before history.

  78. Sam

    I mean, if it's what everything does I can do that too, the spec just makes it sound like self-presence is the thing that means you're joined. What does it matter if I've gotten history or not yet?

  79. Kev

    And you almost always want to know what’s live messages and what’s join context.

  80. Kev

    So you need the subject to know you’re done with the history and everything after will be live changes.

  81. Sam

    Oh yah, I guess I might want to draw a line after history or something to distinguish it for the user

  82. Kev

    Also, subject is a MUST.

  83. Kev

    Not SHOULd :)

  84. Kev

    Not SHOULD :)

  85. Sam

    oops, so it is. Weird, I swear I just read that and it said SHOULD.

  86. Zash

    SHALL == MUST?

  87. Sam


  88. Zash


  89. Sam

    Still, I'm joined after self-presence. When I get subject, I can draw the line and start live messages. Does it matter that I was already joined?

  90. Sam

    Anything I send I'll still get the reflection back after the history (I assume).

  91. Zash

    If you wanna have a "ready" signal, separate from "success", I suppose.

  92. Zash

    May matter for UI stuff.

  93. Sam

    What's the difference between "ready" and "success", I guess?

  94. Sam

    I just don't see how it would matter in the UI or anything

  95. Zash

    If you wanna show a spinner or something while it's throwing history at you?

  96. Sam

    In that case it seems like I'd just do the Join, show the spinner, then when I get the history back I'd clear the spinner. I don't have to block the join call on it.

  97. Zash

    I think some clients don't let you start writing until then

  98. Sam

    The writing thing makes sense, but this is a library so the clients could always still do that.

  99. Sam

    Returning on self-presence seems more flexible in that way; clients can still do either. If I return on subject they are stuck with that.

  100. Sam

    But also I have a nagging suspicion that if everyone else does subject there's probably a good reason that actually will break later that I'm not thinking of.

  101. Sam

    > // SendPresence is like Send except that it returns an error if the first token > // read from the stream is not a Presence start token and blocks until an error > // response is received or the context times out. > // Presences are generally fire-and-forget meaning that the success behavior of > // SendPresence is to time out and that methods such as Send should normally be > // used instead. > // It is thus mainly for use by extensions that define an extension-namespaced > // success response to a presence being sent and need a mechanism to track > // general error responses without handling every single presence sent through > // the session to see if it has a matching ID. > // > // SendPresence is safe for concurrent use by multiple goroutines. Good enough (I hope).

  102. Sam

    Thanks again for all the help.

  103. Zash

    Sam, what's that about returning an error if not reading a presence from the stream?

  104. Sam

    Wrong type of stream, it's confusing out of context but it copies XML tokens so you'd do SendPresence(timeout, Presence{Type: whatever}.Wrap(somepayload)) which returns an XML token stream that gets copied to the XMPP stream.

  105. Sam

    See SendIQ (https://pkg.go.dev/mellium.im/xmpp#Session.SendIQ) for an already existing example.

  106. Sam

    I should probably not re-use "stream" in the docs, that's confusing.

  107. Zash

    Sounds a bit overloaded, yes.

  108. Sam

    "first token read from the reader" or something will fix that. Done.

  109. Sam

    Or "from the input".

  110. Sam

    There are now 16 basic sending methods that match (Send|Encode)(Message|Presence|IQ)?(Element)?

  111. Sam

    I don't love that, but it does work quite well in my experience so far even if it's a lot of options.

  112. is_bru

    Does anyone still use talkonaut?

  113. Martin

    What is a talkonaut?

  114. Sam

    Looks like it's similar to jmp.chat? The website doesn't work for me, so I dunno if it still exists or not.

  115. Martin

    Ah, so a telephone xmpp transport. Never used one of those.

  116. moparisthebest

    > Talkonaut by GTalk2VoIP, Inc.

  117. moparisthebest


  118. MattJ

    Wow, haven't heard of Talkonaut for a while

  119. Martin

    GTalk2VoIP sounds like it's long dead also.

  120. Martin

    When was gtalk switched off?

  121. MattJ

    Never, it's still going I think :)

  122. MattJ

    Still responding on 5222 anyway

  123. Martin

    Oh, I thought it's dead for a long time already.

  124. Holger

    s2s is dead, c2s isn't.

  125. MattJ

    Yeah, they announced it was. Then it continued to work for years. Then they eventually turned off s2s (which nobody used anyway because it didn't do TLS). Now they're shutting down Hangouts, which is likely tied up in the same infrastructure, so it possibly might actually disappear soon.

  126. Martin

    Is there even a client nowadays? Can't really follow googles pace of inventing and killing chat systems. 😁

  127. MattJ

    You can use any XMPP client, but it only really works with other XMPP clients. If people are using the Google Hangouts client they appear online but don't receive messages.

  128. MattJ

    All that based on old observations, I haven't poked around in the past year or so

  129. Martin

    Sounds like a long forgotten service running on a long forgotten machine in the basement. 😂

  130. MattJ

    Well, that Hangouts users appear online suggests it's all the same infrastructure, and the Hangouts conferences in the browser used XMPP for signalling even after they announced the end of GTalk, so it's very likely still all production.

  131. MattJ

    But now Hangouts is supposedly dead (EOL June), all that may change

  132. Link Mauve

    MattJ, s2s also didn’t let outsiders communicate with Hangouts users, fyi.

  133. MattJ

    or they may just keep it limping along for those few enterprise customers who insist they can't live without it

  134. Link Mauve

    With an extremely annoying failure model, where our messages would simply get redirected to /dev/null.

  135. MattJ


  136. Martin

    Just pretend it never existed and keep on working on xmpp world domination. 😃

  137. Link Mauve

    Also Hangouts video calls from the Firefox plugin were printing MUC and Jingle debug stuff on stderr.

  138. kamui

    Is there a way I can upload files when using encryption?

  139. kamui

    Is there a way I can upload files?

  140. kamui

    everytime I try to do it, it just errors out with "File transfer failed"

  141. kamui


  142. Martin

    What server do you use?

  143. kamui