multi-threading with websocket

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

multi-threading with websocket

Ben Coman
The websockets guide here....
https://ci.inria.fr/pharo-contribution/job/EnterprisePharoBook/lastSuccessfulBuild/artifact/book-result/WebSockets/WebSockets.html

says "Reading and sending are completely separate and independent" and the class comment says its "full-duplex".  From these I presume sending and receiving are okay to occur in separate threads, but this is not explicitly stated, so can someone confirm this?

So for the given example....
| webSocket |
webSocket := ZnWebSocket to: 'ws://echo.websocket.org'.
[ webSocket
   sendMessage: 'Pharo Smalltalk using Zinc WebSockets !';
   readMessage ] ensure: [ webSocket close ].

re-implementing as follows seems to work...
webSocket := ZnWebSocket to: 'ws://echo.websocket.org'.
[ webSocket runWith: [ :msg | Transcript crShow: msg ] ] forkAt: 35.
webSocket sendMessage: 'Pharo Smalltalk using Zinc WebSockets !'.
webSocket sendMessage: 'Another multi-thread echo'.
webSocket close

but that could just be by luck, so I ask.


btw, if I don't send the #close in the last line, after ~30 seconds I get an error
    ConnectionClosed: Cannot write data
which seems reasonable that the other end timed out and closed the connection,

but when I send the #close, after ~30 seconds I get an error...
   PrimitiveFailed: primitive #primSocketReceiveDataAvailable: in Socket failed
which is unfriendly.  What is the best way to neatly stop trying to receive data when we explicitly close the websocket?

cheers -ben


P.S.  I wonder if when a ZnWebSocket is closed, it might be worthwhile
to do  "role:=#closed"  to provide some visibility of its state in its GTInspector [Raw] tab..


Reply | Threaded
Open this post in threaded view
|

Re: multi-threading with websocket

Sven Van Caekenberghe-2
Ben,

> On 18 Feb 2018, at 15:29, Ben Coman <[hidden email]> wrote:
>
> The websockets guide here....
> https://ci.inria.fr/pharo-contribution/job/EnterprisePharoBook/lastSuccessfulBuild/artifact/book-result/WebSockets/WebSockets.html
>
> says "Reading and sending are completely separate and independent" and the class comment says its "full-duplex".  From these I presume sending and receiving are okay to occur in separate threads, but this is not explicitly stated, so can someone confirm this?

The reading and the writing over a web socket connection are independent, so yes that would be OK. Of course, they would both share the same network stream (just use each half independently) - that normally works fine.

> So for the given example....
> | webSocket |
> webSocket := ZnWebSocket to: 'ws://echo.websocket.org'.
> [ webSocket
>    sendMessage: 'Pharo Smalltalk using Zinc WebSockets !';
>    readMessage ] ensure: [ webSocket close ].
>
> re-implementing as follows seems to work...
> webSocket := ZnWebSocket to: 'ws://echo.websocket.org'.
> [ webSocket runWith: [ :msg | Transcript crShow: msg ] ] forkAt: 35.
> webSocket sendMessage: 'Pharo Smalltalk using Zinc WebSockets !'.
> webSocket sendMessage: 'Another multi-thread echo'.
> webSocket close
>
> but that could just be by luck, so I ask.

No, that should work.

> btw, if I don't send the #close in the last line, after ~30 seconds I get an error
>     ConnectionClosed: Cannot write data
> which seems reasonable that the other end timed out and closed the connection,
>
> but when I send the #close, after ~30 seconds I get an error...
>    PrimitiveFailed: primitive #primSocketReceiveDataAvailable: in Socket failed
> which is unfriendly.  What is the best way to neatly stop trying to receive data when we explicitly close the websocket?

Of course that fails, you fork a reading loop containing #runWith: which has to end/stop somehow, the lazy way is by allowing an error to bubble up.

> cheers -ben
>
>
> P.S.  I wonder if when a ZnWebSocket is closed, it might be worthwhile
> to do  "role:=#closed"  to provide some visibility of its state in its GTInspector [Raw] tab..

Maybe, but there is #isConnected and the Socket inspector 'Socket Info' shows lots of details, you can rely on that.

Sven