Alright. Thankfully someone can help me out before I pull my hair out. I have this very odd issue. I'm using aleph/manifold to connect to a websocket, and s/consume
doesn't seem to be triggering at all and I really don't know why. Evaluating each relevant line one at a time works from the repl, just not within a function. Here's the exact line that doesn't trigger: https://github.com/eslachance/dithcord/blob/master/src/dithcord/core.clj#L121
what's the manifold version?
@dm3 I just have [aleph "0.4.1"]
@eslachance what does printing the stream that you consume show?
e.g.
boot.user=> (manifold.stream/stream)
<< stream: {:pending-puts 0, :drained? false, :buffer-size 0, :permanent? false, :type "manifold", :sink? true, :closed? false, :pending-takes 0, :buffer-capacity 0, :source? true} >>
after you start consuming the stream, it should have a :pending-takes 1
and :closed?
should be false
and :drained?
should also be false
When I call that function (ws-connect) it returns the session, which has the stream as a socket
and printing out (:socket @session)
does show that stream
ws
is the stream you're consuming
yes which I have as (swap! session assoc :socket ws)
let me see about drained
what happens if you just do
(let [x @(http/websocket-client "<wss://gateway.discord.gg/v?6&encoding=json>")]
(s/consume #(println "DEBUG" %) x))
?.... nothing
well sorry it returns nil
to be precise
yes
which means you are not receiving anything on that URL?
nothing else, no message, not output.
what if you try another WS client?
But I am though if I do
(def conn @(http/websocket-client "<wss://gateway.discord.gg/?v=6&encoding=json>"))
(s/on-closed conn (fn [] (prn "closed")))
(s/consume (fn [msg] (prn msg)) conn)
then I do get a messageI get a first packet, and then I get a closed message after a second or so because the websocket is expecting an identity packet
which, if I provide it, does work
So I'm receiving packets fine when I def the connection. But when I use let
it doesn't work
that doesn't affect anything
I was previously using http.async.client
, which worked fine except for the fact that it crashes the websocket on large packets (a bug in the java lib it uses)
so you have some code using aleph
that works?
I do. those 3 lines work
That's the packet
and you are saying that
(let [conn @(http/websocket-client "<wss://gateway.discord.gg/?v=6&encoding=json>"))]
(s/on-closed conn (fn [] (prn "closed")))
(s/consume (fn [msg] (prn msg)) conn))
doesn't?hmm
wait a sec. no it does.
...
but...
(let [x @(http/websocket-client "<wss://gateway.discord.gg/v?6&encoding=json>")]
(s/consume #(println "DEBUG" %) x))
didn't work. IT didn't print out that packetthe heck?
maybe there was no packet?
try looking with wireshark or something?
I don't even know what that is >.<
but really I know this API
we're talkinga bout Discord here it always sends a packet
consistently
the URL is wrong
OH MY GOD
...
Thank you.
I shall take my shame and go fix the error
happens π
Obviously, this does bring to light that aleph doesn't have an "on-error" event cough
(well manifold doesn't?)
it's probably closing the stream, no?
and there's https://github.com/ztellman/manifold/issues/95
which has no definite answer
True, but when a websocket closes, it has a reason to close. Getting that reason would be... useful.
agree
I mean we have s/on-close
why not s/on-error
. I feel that's expected, and consistent.
And also consistent with other libraries
you can contribute to the issue above
all thoughts welcome π
Obviously!
Once I get this all working I'm planning a series of video tutorials on various things clojure-related in the shape of a development story for my library
But that's once I get it working ^_^
Any way to handle a zlib compressed packet? It shows up as #object["[B" 0x7282913c "[B@7282913c"]
if I just print it to console, not exactly sure how to handle that
I guess you need to decompress it yourself
using e.g. http://docs.oracle.com/javase/7/docs/api/java/util/zip/Inflater.html
And the java interop adventure beings....
this seems like an approach - https://github.com/amatus/GNUnet-in-Clojure/blob/master/src/main/clojure/org/gnu/clojure/gnunet/zip.clj
Wait what about byte-streams?
ooooh
I feel like I'm so close though
"x?????0\fE??k???]?????A?t\"??K??\b??e2???vG?G???\n\rz??????B/;X/?&??\n??`??\r?Z???????z ??9?m??_?L??;?S??*8.??(?c4!8%????0?1/?}Y?B?i??\\???BY????E??\r?f??)i\fΒΊ?Z??$??u??+??2<?\r?B&\"5?1LIz?!*?Iz??,?l?`???/?????Y??t?Rh??R????y??2??+????????NGa???\r??R8?u??\b+c????*\n???k????ab??q?u?G??.\\?4?}??U?f?r???l?r"
Oh btw, @dm3 that approach did work, I included it in my project, and used the following line on the incoming packet:
(String. (byte-array (z/inflate msg)))
(z/ being that zip.clj file)Took a lot of mucking around and some help from other people but it works!