Message from discussion
Clojurescript long polling questions
Received: by 10.236.165.99 with SMTP id d63mr11484558yhl.7.1336195020534;
Fri, 04 May 2012 22:17:00 -0700 (PDT)
X-BeenThere: clojure@googlegroups.com
Received: by 10.236.73.226 with SMTP id v62ls4189749yhd.7.gmail; Fri, 04 May
2012 22:16:52 -0700 (PDT)
Received: by 10.101.7.34 with SMTP id k34mr3489366ani.15.1336195012687;
Fri, 04 May 2012 22:16:52 -0700 (PDT)
Received: by 10.101.7.34 with SMTP id k34mr3489364ani.15.1336195012643;
Fri, 04 May 2012 22:16:52 -0700 (PDT)
Return-Path: <dusan.milorado...@gmail.com>
Received: from mail-yx0-f181.google.com (mail-yx0-f181.google.com [209.85.213.181])
by gmr-mx.google.com with ESMTPS id z66si11241120yhj.0.2012.05.04.22.16.52
(version=TLSv1/SSLv3 cipher=OTHER);
Fri, 04 May 2012 22:16:52 -0700 (PDT)
Received-SPF: pass (google.com: domain of dusan.milorado...@gmail.com designates 209.85.213.181 as permitted sender) client-ip=209.85.213.181;
Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of dusan.milorado...@gmail.com designates 209.85.213.181 as permitted sender) smtp.mail=dusan.milorado...@gmail.com; dkim=pass header...@gmail.com
Received: by yenq2 with SMTP id q2so3650142yen.12
for <clojure@googlegroups.com>; Fri, 04 May 2012 22:16:52 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20120113;
h=mime-version:in-reply-to:references:date:message-id:subject:from:to
:content-type;
bh=TxjZ8K1QXQvUtyDKNrH7CFOgUoVElW1HpktXHH0teEQ=;
b=TNPm576vYuxPueE7rewPimbccFYQvpePOeqeDZe0Bot5V1YYlEhWHgVCqWeDVgPtTA
FIx+FuCKpzkd6gYVwzUNc9BABbFq9Nc+PuRpeOIr90NgQ1MX0upHIQI5zuT3cwtzriTF
YqrNPyFJS0szn0+9QhEizYj40EYX7UPBbW0oD9U8lWg12J7VsrQHBzrtq+Z4PJz3Auf2
gZ4uZ7PE8ieQCl+yfSgeCrsBpn/Fe2ndo8wyNx27J8K3bz+LgG/4TUrPSrGSne6wy+hX
HF9Whchh4gU0N/g9SwKMxPTTuX7Jdh4SXQKSy9h9XzVXlgfkIiYo0W8eJveszbDnRLBa
Yn0A==
MIME-Version: 1.0
Received: by 10.236.173.232 with SMTP id v68mr10801038yhl.97.1336195012305;
Fri, 04 May 2012 22:16:52 -0700 (PDT)
Received: by 10.146.167.16 with HTTP; Fri, 4 May 2012 22:16:52 -0700 (PDT)
In-Reply-To: <32091190.525.1336130887523.JavaMail.geo-discussion-forums@pbaf5>
References: <3597767.3330.1335780005360.JavaMail.geo-discussion-forums@vbbfk16>
<366be433-fd29-4287-bdba-791bcba14...@e15g2000vbt.googlegroups.com>
<CABJPRyB6AnQTuW_anvK4gQEwy774_GwwZvOpK7o_g+d1as-...@mail.gmail.com>
<CAP880hHRUO_fwJQ-vBcRf9szaXzWcxm3dnumtZcmY9-xRgN...@mail.gmail.com>
<CABJPRyBK9NSDtGL6Qh_WW=e4sm5RfqkBrPKmgT8-LfP3rB4...@mail.gmail.com>
<32091190.525.1336130887523.JavaMail.geo-discussion-forums@pbaf5>
Date: Sat, 5 May 2012 09:16:52 +0400
Message-ID: <CABJPRyC5JKxkFO+HbRB4k43m73HkVAqbFfkxyOqZWrExf=D...@mail.gmail.com>
Subject: Re: Clojurescript long polling questions
From: Dusan Miloradovic <dusan.milorado...@gmail.com>
To: clojure@googlegroups.com
Content-Type: multipart/alternative; boundary=20cf30563c170f252404bf432562
--20cf30563c170f252404bf432562
Content-Type: text/plain; charset=ISO-8859-1
Thanks for great answers Daniel and Zach
Dusan
On Fri, May 4, 2012 at 3:28 PM, Zach Tellman <ztell...@gmail.com> wrote:
> That documentation is for the Lamina library, and describes how
> full-duplex client connections are represented. If you created a TCP
> client, all that would be true.
>
> However, you are writing a server, and using HTTP, which is a much more
> structured protocol. Each request takes only a single response, which
> means that the 'ch' given to the handler function can only accept a single
> response value. The XHR mechanism exists to allow long gaps between
> request and response, but still only supports single messages back and
> forth. There exist protocols that emulate a full-duplex mechanism on top
> of HTTP, such as socket.io, but Aleph doesn't currently support that.
>
> However, if you opened a WebSocket connection to the server, and set
> :websocket to true in the server parameters, the 'ch' *would* be a
> full-duplex connection. Based on my understanding of what you're trying to
> do, that may be a good solution.
>
> Zach
>
>
> On Thursday, May 3, 2012 11:45:50 AM UTC+5:30, Dusan wrote:
>>
>> Hmm,
>>
>> acording to the aleph documentation:
>>
>> A connection to a server is represented by a result-channel<https://github.com/ztellman/lamina/wiki/Result-Channels>.
>> If the connection is successful, the result-channel will emit a channel
>> that can be used to communicate with the server. *When the connection
>> closes, the channel will close.*
>>
>> I thought that the whole point of having the xhr instance in
>> clojurescript is to have one "persistent" http channel, unlike the regular
>> http.
>> This is the output from the console after the first(and only) response is
>> received:
>>
>> netstat -a
>> Active Internet connections (including servers)
>> Proto Recv-Q Send-Q Local Address Foreign Address (state)
>> ..the next two are for REPL
>> tcp4 0 0 localhost.9000 localhost.35075
>> ESTABLISHED
>> tcp4 0 0 localhost.35075 localhost.9000
>> ESTABLISHED
>> ...connection to aleph server remained open, even if the HTTP request
>> iahs ended:
>> *tcp4 0 0 localhost.8080 localhost.35852
>> ESTABLISHED
>> tcp4 0 0 localhost.35852 localhost.8080
>> ESTABLISHED*
>> ... these are for swank
>> tcp4 0 0 localhost.4005 localhost.51638
>> ESTABLISHED
>> tcp4 0 0 localhost.51638 localhost.4005
>> ESTABLISHED
>>
>> Also I dont see why this:
>> (defn longpoll-new [ch request]
>> (siphon k ch) )
>>
>> closes the connection, I thought it should safely redirect all the
>> messages from k.
>>
>> What do I miss here?
>>
>> Thanks for the help
>> Dusan
>>
>> As you can see the connection from the browser remains. It does close
>> after 5 minutes though.
>> On Thu, May 3, 2012 at 12:36 AM, Daniel Renfer <d...@kronkltd.net> wrote:
>>
>>> I think your issue is, you say you want long polling, but it seems
>>> like what you're looking for is more of HTTP streaming. The result
>>> channel you get in the aleph handler is set up to receive only a
>>> single message and then close. If you want a streaming response,
>>> create a new channel and a request map with that channel as it's body.
>>> Enqueue that response map into the result channel and then siphon the
>>> the messages from your source channel to the "body" channel.
>>>
>>> I've found that it's best / you need to put a newline between messages
>>> so that the response will be properly flushed.
>>>
>>> I'm pretty sure I don't need the future, but here's how I've done it.
>>> https://github.com/duck1123/**jiksnu/blob/**
>>> 8d66c34f1be8b0b29b0959a18cfdc3**15346c2bd2/src/jiksnu/actions/**
>>> stream_actions.clj#L128<https://github.com/duck1123/jiksnu/blob/8d66c34f1be8b0b29b0959a18cfdc315346c2bd2/src/jiksnu/actions/stream_actions.clj#L128>
>>>
>>> Hope that helps.
>>>
>>> On Tue, May 1, 2012 at 7:17 AM, Dusan Miloradovic
>>> <dusan.milorado...@gmail.com> wrote:
>>> > Unfortunaltely that does not work either, thank you for the help. It
>>> stops
>>> > receiving after the first message, just like before. Here is the
>>> updated
>>> > version:
>>> >
>>> > (defn long-poll-newest
>>> > ([url callback error-callback]
>>> > (long-poll-newest url callback error-callback
>>> (net/xhr-connection)))
>>> > ([url callback error-callback xhr1]
>>> > (do
>>> > (event/listen xhr1
>>> > :success
>>> > (fn[e]
>>> > (callback (. xhr1 (getResponseText)))
>>> > (long-poll-newest url callback error-callback
>>> > xhr1)
>>> >
>>> > ))
>>> > (event/listen xhr1
>>> > :error
>>> > (fn[e]
>>> > (when error-callback
>>> > (println "entered the error callback")
>>> > (error-callback e)
>>> > )))
>>> > (event/listen xhr1
>>> > :timeout
>>> > (fn[e]
>>> > (long-poll-newest url callback error-callback
>>> > xhr1)
>>> > ))
>>> > (net/transmit xhr1 url))))
>>> >
>>> > Here is the working version with opening and closing of the connection
>>> on
>>> > every call, at least it should not leak xhr connections:
>>> > (defn long-poll
>>> > ([url callback error-callback]
>>> > (let [kk (net/xhr-connection)]
>>> > (do
>>> > (event/listen-once kk
>>> > :complete
>>> > (fn[e]
>>> > (let [isSucc (. kk (isSuccess))
>>> > ** ek (. kk (getLastErrorCode))
>>> > ** isErr (or (= ek ec/EXCEPTION)
>>> (= ek
>>> > ec/HTTP_ERROR))]
>>> > ** (do
>>> > ** (when isSucc
>>> > ** (callback (. kk
>>> (getResponseText))))
>>> > ** (. kk (dispose))
>>> > ** (if isErr
>>> > ** (error-callback e)
>>> > ** (long-poll url callback
>>> error-callback))
>>> > ** ))))
>>> > (net/transmit kk url)))
>>> > ))
>>> >
>>> > Thx
>>> >
>>> >
>>> >
>>> >
>>> > On Tue, May 1, 2012 at 2:17 PM, Gijs S. <gijsstuur...@gmail.com>
>>> wrote:
>>> >>
>>> >> The order of arguments you pass to long-poll-newest doesn't look
>>> >> right.
>>> >>
>>> >> You defined long-poll-newest to optionally take a fourth parameter for
>>> >> the existing xhr connection. However, when calling long-poll-newest
>>> >> you pass the existing xhr connection as the first argument.
>>> >>
>>> >> Replace
>>> >> (long-poll-newest xhr1 url callback error-callback)
>>> >> with
>>> >> (long-poll-newest url callback error-callback xhr1)
>>> >>
>>> >> Also, all of the (do ..)'s are unnecessary. 'let', 'fn' and 'when'
>>> >> evaluate the body in an implicit 'do' themselves.
>>> >>
>>> >> The overall approach to reuse the connection looks fine otherwise.
>>> >>
>>> >> -Gijs
>>> >>
>>> >> On Apr 30, 12:00 pm, Dusan <dusan.milorado...@gmail.com> wrote:
>>> >> > I am trying to figure out how to setup the long polling from the
>>> >> > clojurescript.
>>> >> >
>>> >> > I use aleph on the server side. Here is the trivial aleph handler
>>> and
>>> >> > related code:
>>> >> >
>>> >> > (def k (permanent-channel))
>>> >> >
>>> >> > (receive-all k (fn[x] (println "got " x)))
>>> >> >
>>> >> > (defn longpoll-new [ch request]
>>> >> > (siphon k ch)
>>> >> > )
>>> >> >
>>> >> > (defn send-mes [k mes]
>>> >> > (enqueue k ((comp r/response pr-str) mes)))
>>> >> >
>>> >> > On the clojurescript side I am trying to open one xhr connection,
>>> and
>>> >> > use
>>> >> > it for all subsequent calls:
>>> >> >
>>> >> > (defn long-poll-newest
>>> >> > ([url callback error-callback]
>>> >> > (long-poll-newest url callback error-callback
>>> >> > (net/xhr-connection)))
>>> >> > ([url callback error-callback xhr1]
>>> >> > (do
>>> >> > (event/listen xhr1
>>> >> > :success
>>> >> > (fn[e]
>>> >> > (do
>>> >> > (callback (. xhr1 (getResponseText)))
>>> >> > (long-poll-newest xhr1 url callback
>>> >> > error-callback)
>>> >> > )))
>>> >> > (event/listen xhr1
>>> >> > :error
>>> >> > (fn[e]
>>> >> > (when error-callback
>>> >> > (do
>>> >> > (println "entered the error callback")
>>> >> > (error-callback e)
>>> >> > )
>>> >> > )))
>>> >> > (event/listen xhr1
>>> >> > :timeout
>>> >> > (fn[e]
>>> >> > (do
>>> >> > (long-poll-newest xhr1 url callback
>>> >> > error-callback)
>>> >> > )
>>> >> > ))
>>> >> > (net/transmit xhr1 url))
>>> >> > ))
>>> >> >
>>> >> > Unfiortunatelly, this receives just the first message from server,
>>> and
>>> >> > then
>>> >> > it stops.
>>> >> >
>>> >> > This is the version that is working:
>>> >> > (defn long-poll [url callback error-callback]
>>> >> > (let [xhr1 (net/xhr-connection)]
>>> >> > (do
>>> >> > (event/listen xhr1
>>> >> > :success
>>> >> > (fn[e]
>>> >> > (do
>>> >> > (callback (. xhr1 (getResponseText)))
>>> >> > (long-poll url callback error-callback)
>>> >> > )))
>>> >> > (event/listen xhr1
>>> >> > :error
>>> >> > (fn[e]
>>> >> > (when error-callback
>>> >> > (do
>>> >> > (println "entered the error callback")
>>> >> > (error-callback e)
>>> >> > )
>>> >> > )))
>>> >> > (event/listen xhr1
>>> >> > :timeout
>>> >> > (fn[e]
>>> >> > (do
>>> >> > (long-poll url callback error-callback)
>>> >> > )
>>> >> > ))
>>> >> > (net/transmit xhr1 url))))
>>> >> >
>>> >> > In this version I am closing the original xhr, I am creating the
>>> new one
>>> >> > for each request.
>>> >> > How can I make the first version functional, what do I miss?
>>> >> >
>>> >> > Dusan
>>> >>
>>> >> --
>>> >> You received this message because you are subscribed to the Google
>>> >> Groups "Clojure" group.
>>> >> To post to this group, send email to clojure@googlegroups.com
>>> >> Note that posts from new members are moderated - please be patient
>>> with
>>> >> your first post.
>>> >> To unsubscribe from this group, send email to
>>> >> clojure+unsubscribe@**googlegroups.com<clojure%2Bunsubscribe@googlegroups.com>
>>> >> For more options, visit this group at
>>> >> http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>> >
>>> >
>>> > --
>>> > You received this message because you are subscribed to the Google
>>> > Groups "Clojure" group.
>>> > To post to this group, send email to clojure@googlegroups.com
>>> > Note that posts from new members are moderated - please be patient
>>> with your
>>> > first post.
>>> > To unsubscribe from this group, send email to
>>> > clojure+unsubscribe@**googlegroups.com<clojure%2Bunsubscribe@googlegroups.com>
>>> > For more options, visit this group at
>>> > http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clojure@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+unsubscribe@**googlegroups.com<clojure%2Bunsubscribe@googlegroups.com>
>>> For more options, visit this group at
>>> http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>>
>>
>> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscribe@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>
--20cf30563c170f252404bf432562
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Thanks for great answers Daniel and Zach<div><br></div><div>Dusan<br><br><d=
iv class=3D"gmail_quote">On Fri, May 4, 2012 at 3:28 PM, Zach Tellman <span=
dir=3D"ltr"><<a href=3D"mailto:ztell...@gmail.com" target=3D"_blank">zt=
ell...@gmail.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">That documentation is for the Lamina library=
, and describes how full-duplex client connections are represented. =A0If y=
ou created a TCP client, all that would be true.<div>
<br></div><div>However, you are writing a server, and using HTTP, which is =
a much more structured protocol. =A0Each request takes only a single respon=
se, which means that the 'ch' given to the handler function can onl=
y accept a single response value. =A0The XHR mechanism exists to allow long=
gaps between request and response, but still only supports single messages=
back and forth. =A0There exist protocols that emulate a full-duplex mechan=
ism on top of HTTP, such as <a href=3D"http://socket.io" target=3D"_blank">=
socket.io</a>, but Aleph doesn't currently support that.</div>
<div><br></div><div>However, if you opened a WebSocket connection to the se=
rver, and set :websocket to true in the server parameters, the 'ch'=
*would* be a full-duplex connection. =A0Based on my understanding of what =
you're trying to do, that may be a good solution.</div>
<span class=3D"HOEnZb"><font color=3D"#888888"><div><br></div></font></span=
><div><span class=3D"HOEnZb"><font color=3D"#888888">Zach</font></span><div=
><div class=3D"h5"><br><div><br>On Thursday, May 3, 2012 11:45:50 AM UTC+5:=
30, Dusan wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
Hmm,<br><br>acording to the aleph documentation:<br><br>A connection to a s=
erver is represented by a <a href=3D"https://github.com/ztellman/lamina/wik=
i/Result-Channels" target=3D"_blank">result-channel</a>.
If the connection is successful, the result-channel will emit a=20
channel that can be used to communicate with the server. <b>When the=20
connection closes, the channel will close.</b><br><br>I thought that the wh=
ole point of having the xhr instance in clojurescript is to have one "=
persistent" http channel, unlike the regular http.<br>This is the outp=
ut from the console after the first(and only) response is received:<br>
<br>=A0netstat -a<br>Active Internet connections (including servers)<br>Pro=
to Recv-Q Send-Q=A0 Local Address=A0=A0=A0=A0=A0=A0=A0=A0=A0 Foreign Addres=
s=A0=A0=A0=A0=A0=A0 (state)<br>..the next two are for REPL<br>tcp4=A0=A0=A0=
=A0=A0=A0 0=A0=A0=A0=A0=A0 0 localhost.9000=A0=A0=A0=A0=A0=A0=A0=A0 localho=
st.35075=A0=A0=A0=A0=A0=A0=A0 ESTABLISHED<br>
tcp4=A0=A0=A0=A0=A0=A0 0=A0=A0=A0=A0=A0 0 localhost.35075=A0=A0=A0=A0=A0=A0=
=A0 localhost.9000=A0=A0=A0=A0=A0=A0=A0=A0 ESTABLISHED<br>...connection to =
aleph server remained open, even if the HTTP request iahs ended:<br><b>tcp4=
=A0=A0=A0=A0=A0=A0 0=A0=A0=A0=A0=A0 0 localhost.8080=A0=A0=A0=A0=A0=A0=A0=
=A0 localhost.35852=A0=A0=A0=A0=A0=A0=A0 ESTABLISHED<br>
tcp4=A0=A0=A0=A0=A0=A0 0=A0=A0=A0=A0=A0 0 localhost.35852=A0=A0=A0=A0=A0=A0=
=A0 localhost.8080=A0=A0=A0=A0=A0=A0=A0=A0 ESTABLISHED</b><br>... these are=
for swank<br>tcp4=A0=A0=A0=A0=A0=A0 0=A0=A0=A0=A0=A0 0 localhost.4005=A0=
=A0=A0=A0=A0=A0=A0=A0 localhost.51638=A0=A0=A0=A0=A0=A0=A0 ESTABLISHED<br>t=
cp4=A0=A0=A0=A0=A0=A0 0=A0=A0=A0=A0=A0 0 localhost.51638=A0=A0=A0=A0=A0=A0=
=A0 localhost.4005=A0=A0=A0=A0=A0=A0=A0=A0 ESTABLISHED<br>
<br>Also I dont see why this:<br>(defn longpoll-new [ch request]<br>
=A0=A0 (siphon k ch) )<br><br>closes the connection, I thought it should sa=
fely redirect all the messages from k.<br><br>What do I miss here?<br><br>T=
hanks for the help <br>Dusan<br><br>As you can see the connection from the =
browser remains. It does close after 5 minutes though.<br>
<div class=3D"gmail_quote">On Thu, May 3, 2012 at 12:36 AM, Daniel Renfer <=
span dir=3D"ltr"><<a href=3D"mailto:d...@kronkltd.net" target=3D"_blank"=
>d...@kronkltd.net</a>></span> wrote:<br><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I think your issue is, you say you want long polling, but it seems<br>
like what you're looking for is more of HTTP streaming. The result<br>
channel you get in the aleph handler is set up to receive only a<br>
single message and then close. If you want a streaming response,<br>
create a new channel and a request map with that channel as it's body.<=
br>
Enqueue that response map into the result channel and then siphon the<br>
the messages from your source channel to the "body" channel.<br>
<br>
I've found that it's best / you need to put a newline between messa=
ges<br>
so that the response will be properly flushed.<br>
<br>
I'm pretty sure I don't need the future, but here's how I'v=
e done it.<br>
<a href=3D"https://github.com/duck1123/jiksnu/blob/8d66c34f1be8b0b29b0959a1=
8cfdc315346c2bd2/src/jiksnu/actions/stream_actions.clj#L128" target=3D"_bla=
nk">https://github.com/duck1123/<u></u>jiksnu/blob/<u></u>8d66c34f1be8b0b29=
b0959a18cfdc3<u></u>15346c2bd2/src/jiksnu/actions/<u></u>stream_actions.clj=
#L128</a><br>
<br>
Hope that helps.<br>
<div><div><br>
On Tue, May 1, 2012 at 7:17 AM, Dusan Miloradovic<br>
<<a href=3D"mailto:dusan.milorado...@gmail.com" target=3D"_blank">dusan.=
milorado...@gmail.com</a>> wrote:<br>
> Unfortunaltely that does not work either, thank you for the help. It s=
tops<br>
> receiving after the first message, just like before. Here is the updat=
ed<br>
> version:<br>
><br>
> (defn long-poll-newest<br>
> =A0 ([url callback error-callback]<br>
> =A0=A0=A0=A0 (long-poll-newest=A0 url callback error-callback (net/xhr=
-connection)))<br>
> =A0 ([url callback error-callback xhr1]<br>
> =A0=A0=A0=A0 (do<br>
> =A0=A0=A0=A0=A0=A0 (event/listen xhr1<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 :success<=
br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (fn[e]<br=
>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 (callback (. xhr1 (getResponseText)))<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 (long-poll-newest=A0 url callback error-callback<br>
> xhr1)<br>
><br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 ))<br>
> =A0=A0=A0=A0=A0=A0 (event/listen xhr1<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 :error<br=
>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (fn[e]<br=
>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (wh=
en error-callback<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0 (println "entered the error callback")<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0 (error-callback e)<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 )))<br>
> =A0=A0=A0=A0=A0=A0 (event/listen xhr1<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 :timeout<=
br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (fn[e]<br=
>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 (long-poll-newest=A0 url callback error-callback<br>
> xhr1)<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ))<=
br>
> =A0=A0=A0=A0=A0=A0 (net/transmit xhr1 url))))<br>
><br>
> Here is the working version with opening and closing of the connection=
on<br>
> every call, at least it should not leak xhr connections:<br>
> (defn long-poll<br>
> =A0 ([url callback error-callback]<br>
> =A0=A0=A0=A0 (let [kk (net/xhr-connection)]<br>
> =A0=A0=A0=A0=A0=A0 (do<br>
> =A0=A0=A0=A0=A0=A0=A0=A0 (event/listen-once kk<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 :complete<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 (fn[e]<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0 (let [isSucc (. kk (isSuccess))<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0=A0=A0=A0=A0 ek (. kk (getLastErrorCode))<br=
>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0=A0=A0=A0=A0 isErr (or (=3D ek ec/EXCEPTION)=
(=3D ek<br>
> ec/HTTP_ERROR))]<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0 (do<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0=A0=A0 (when isSucc<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0=A0=A0=A0=A0 (callback (. kk (getResponseTex=
t))))<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0=A0=A0 (. kk (dispose))<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0=A0=A0 (if isErr<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0=A0=A0=A0=A0 (error-callback e)<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0=A0=A0=A0=A0 (long-poll url callback error-c=
allback))<br>
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0<u></u>=A0=A0=A0 ))))<br>
> =A0=A0=A0=A0=A0=A0=A0=A0 (net/transmit kk url)))<br>
> =A0=A0=A0=A0 ))<br>
><br>
> Thx<br>
><br>
><br>
><br>
><br>
> On Tue, May 1, 2012 at 2:17 PM, Gijs S. <<a href=3D"mailto:gijsstuu=
r...@gmail.com" target=3D"_blank">gijsstuur...@gmail.com</a>> wrote:<br>
>><br>
>> The order of arguments you pass to long-poll-newest doesn't lo=
ok<br>
>> right.<br>
>><br>
>> You defined long-poll-newest to optionally take a fourth parameter=
for<br>
>> the existing xhr connection. However, when calling long-poll-newes=
t<br>
>> you pass the existing xhr connection as the first argument.<br>
>><br>
>> Replace<br>
>> (long-poll-newest xhr1 url callback error-callback)<br>
>> with<br>
>> (long-poll-newest url callback error-callback xhr1)<br>
>><br>
>> Also, all of the (do ..)'s are unnecessary. 'let', =
9;fn' and 'when'<br>
>> evaluate the body in an implicit 'do' themselves.<br>
>><br>
>> The overall approach to reuse the connection looks fine otherwise.=
<br>
>><br>
>> -Gijs<br>
>><br>
>> On Apr 30, 12:00=A0pm, Dusan <<a>dusan.milorado...@gmail.com</a=
>> wrote:<br>
>> > I am trying to figure out how to setup the long polling from =
the<br>
>> > clojurescript.<br>
>> ><br>
>> > I use aleph on the server side. Here is the trivial aleph han=
dler and<br>
>> > related code:<br>
>> ><br>
>> > (def k (permanent-channel))<br>
>> ><br>
>> > (receive-all k (fn[x] (println "got " x)))<br>
>> ><br>
>> > (defn longpoll-new [ch request]<br>
>> > =A0 (siphon k ch)<br>
>> > =A0 )<br>
>> ><br>
>> > (defn send-mes [k mes]<br>
>> > =A0 (enqueue k ((comp r/response pr-str) mes)))<br>
>> ><br>
>> > On the clojurescript side I am trying to open one xhr connect=
ion, and<br>
>> > use<br>
>> > it for all subsequent calls:<br>
>> ><br>
>> > (defn long-poll-newest<br>
>> > =A0 ([url callback error-callback]<br>
>> > =A0 =A0 =A0(long-poll-newest =A0url callback error-callback<b=
r>
>> > (net/xhr-connection)))<br>
>> > =A0 ([url callback error-callback xhr1]<br>
>> > =A0 =A0 =A0(do<br>
>> > =A0 =A0 =A0 =A0(event/listen xhr1<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0:success<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(fn[e]<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(do<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(callback =
(. xhr1 (getResponseText)))<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(long-poll=
-newest xhr1 url callback<br>
>> > error-callback)<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0)))<br>
>> > =A0 =A0 =A0 =A0(event/listen xhr1<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0:error<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(fn[e]<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(when error-ca=
llback<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(do<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(print=
ln "entered the error callback")<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(error=
-callback e)<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0)<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0)))<br>
>> > =A0 =A0 =A0 =A0(event/listen xhr1<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0:timeout<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(fn[e]<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(do<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(long-poll=
-newest xhr1 url callback<br>
>> > error-callback)<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0)<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0))<br>
>> > =A0 =A0 =A0 =A0(net/transmit xhr1 url))<br>
>> > =A0 =A0 =A0))<br>
>> ><br>
>> > Unfiortunatelly, this receives just the first message from se=
rver, and<br>
>> > then<br>
>> > it stops.<br>
>> ><br>
>> > This is the version that is working:<br>
>> > (defn long-poll [url callback error-callback]<br>
>> > =A0 (let [xhr1 (net/xhr-connection)]<br>
>> > =A0 =A0 (do<br>
>> > =A0 =A0 =A0 (event/listen xhr1<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 :success<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (fn[e]<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (do<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (callback (. =
xhr1 (getResponseText)))<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (long-poll ur=
l callback error-callback)<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 )))<br>
>> > =A0 =A0 =A0 (event/listen xhr1<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 :error<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (fn[e]<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (when error-callb=
ack<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (do<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (println =
"entered the error callback")<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (error-ca=
llback e)<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 )<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 )))<br>
>> > =A0 =A0 =A0 (event/listen xhr1<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 :timeout<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (fn[e]<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (do<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (long-poll ur=
l callback error-callback)<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 )<br>
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ))<br>
>> > =A0 =A0 =A0 (net/transmit xhr1 url))))<br>
>> ><br>
>> > In this version I am closing the original xhr, I am creating =
the new one<br>
>> > for each request.<br>
>> > How can I make the first version functional, what do I miss?<=
br>
>> ><br>
>> > Dusan<br>
>><br>
>> --<br>
>> You received this message because you are subscribed to the Google=
<br>
>> Groups "Clojure" group.<br>
>> To post to this group, send email to <a href=3D"mailto:clojure@goo=
glegroups.com" target=3D"_blank">clojure@googlegroups.com</a><br>
>> Note that posts from new members are moderated - please be patient=
with<br>
>> your first post.<br>
>> To unsubscribe from this group, send email to<br>
>> <a href=3D"mailto:clojure%2Bunsubscribe@googlegroups.com" target=
=3D"_blank">clojure+unsubscribe@<u></u>googlegroups.com</a><br>
>> For more options, visit this group at<br>
>> <a href=3D"http://groups.google.com/group/clojure?hl=3Den" target=
=3D"_blank">http://groups.google.com/<u></u>group/clojure?hl=3Den</a><br>
><br>
><br>
> --<br>
> You received this message because you are subscribed to the Google<br>
> Groups "Clojure" group.<br>
> To post to this group, send email to <a href=3D"mailto:clojure@googleg=
roups.com" target=3D"_blank">clojure@googlegroups.com</a><br>
> Note that posts from new members are moderated - please be patient wit=
h your<br>
> first post.<br>
> To unsubscribe from this group, send email to<br>
> <a href=3D"mailto:clojure%2Bunsubscribe@googlegroups.com" target=3D"_b=
lank">clojure+unsubscribe@<u></u>googlegroups.com</a><br>
> For more options, visit this group at<br>
> <a href=3D"http://groups.google.com/group/clojure?hl=3Den" target=3D"_=
blank">http://groups.google.com/<u></u>group/clojure?hl=3Den</a><br>
<br>
--<br>
You received this message because you are subscribed to the Google<br>
Groups "Clojure" group.<br>
To post to this group, send email to <a href=3D"mailto:clojure@googlegroups=
.com" target=3D"_blank">clojure@googlegroups.com</a><br>
Note that posts from new members are moderated - please be patient with you=
r first post.<br>
To unsubscribe from this group, send email to<br>
<a href=3D"mailto:clojure%2Bunsubscribe@googlegroups.com" target=3D"_blank"=
>clojure+unsubscribe@<u></u>googlegroups.com</a><br>
For more options, visit this group at<br>
<a href=3D"http://groups.google.com/group/clojure?hl=3Den" target=3D"_blank=
">http://groups.google.com/<u></u>group/clojure?hl=3Den</a></div></div></bl=
ockquote></div><br>
</blockquote></div></div></div></div><div class=3D"HOEnZb"><div class=3D"h5=
">
<p></p>
-- <br>
You received this message because you are subscribed to the Google<br>
Groups "Clojure" group.<br>
To post to this group, send email to <a href=3D"mailto:clojure@googlegroups=
.com" target=3D"_blank">clojure@googlegroups.com</a><br>
Note that posts from new members are moderated - please be patient with you=
r first post.<br>
To unsubscribe from this group, send email to<br>
<a href=3D"mailto:clojure%2Bunsubscribe@googlegroups.com" target=3D"_blank"=
>clojure+unsubscribe@googlegroups.com</a><br>
For more options, visit this group at<br>
<a href=3D"http://groups.google.com/group/clojure?hl=3Den" target=3D"_blank=
">http://groups.google.com/group/clojure?hl=3Den</a></div></div></blockquot=
e></div><br></div>
--20cf30563c170f252404bf432562--