Yes, the rumors are true: WebSocket support is coming to Zinc HTTP Components 
and thus to Pharo Smalltalk !

Several people asked for it, but Andy Burnett of Knowinnovation USA provided a 
financial incentive (thanks a lot Andy for sponsoring open-source Smalltalk 
software like that), so I am now putting in the effort to make this happen.


The goal is to add WebSocket (RFC 6455) client and server support over plain 
and TLS/SSL streams (ws:// and wss://) to Zinc HTTP Components maintaining 
compatibility with Pharo 1.3, 1.4 and 2.0, as well as community suported 
portability to Gemstone/Smalltalk and Squeak.

The test for success will be:

Use Pharo Smalltalk as both client and server for the Echo example at 
http://www.websocket.org/echo.html as well as implement the same example 
directly (through a locally served page).

The final code will be open source and MIT licensed. It will include unit 
tests, documentation as well as basic support on the mailing list.


The purpose of this email is twofold: to announce the fact that this is 
happening and to look for early alpha testers that can help shape the API. 


Although as yet unfinished, largely undocumented and untested, still containing 
debugging and tracing code and subject to change, there is already working code 
that meets the functional goals available in the main development Zn repository.

Gofer it
  url: 'http://mc.stfx.eu/ZincHTTPComponents';
  package: 'Zinc-HTTP';
  package: 'Zinc-FileSystem';
  package: 'Zinc-Tests';
  package: 'Zinc-WebSocket-Core';
  package: 'Zinc-WebScoket-Tests';
  load 

The first working example is accessing an existing WebSocket test application 
at http://www.websocket.org/echo.html

ZnWebSocketTests>>#testEchoWebSocketsDotOrg
        | webSocket message |
        webSocket := ZnWebSocket to: 'ws://echo.websocket.org'.
        message := 'Greetings from Pharo Smalltalk @ ', TimeStamp now 
printString.
        webSocket sendMessage: message.
        self assert: webSocket readMessage equals: message.
        webSocket close.

The second working example is Zinc implementing the same echo service itself as 
well as accessing it

ZnWebSocketTests>>#testEchoLocally
        | webSocket message |
        ZnServer startDefaultOn: 1701.
        ZnServer default logToTranscript.
        ZnServer default delegate
                map: 'ws-test' 
                to: [ :request | ZnResponse ok: (ZnEntity html: 
ZnWebSocketDelegate wsTestHtml) ];
                map: 'ws-test-local' 
                to: [ :request | ZnResponse ok: (ZnEntity html: 
ZnWebSocketDelegate wsTestLocalHtml) ];
                map: 'ws-echo'
                to: (ZnWebSocketDelegate new 
                                prefixFromString: 'ws-echo'; 
                                handler: ZnWebSocketEchoHandler new; 
                                yourself).
        webSocket := ZnWebSocket to: 'ws://localhost:1701/ws-echo'.
        message := 'Greetings from Pharo Smalltalk @ ', TimeStamp now 
printString.
        webSocket sendMessage: message.
        self assert: webSocket readMessage equals: message.
        webSocket close.
        ZnServer stopDefault.

Where

ZnWebSocketEchoHandler>>#value: webSocket
        "I implement an echo service conversation as a server:
        reading messages and echoing them back until ConnectionClosed"
        
        [ 
                webSocket runWith: [ :message |
                        self crLog: 'Received message: ', message printString, 
' echoing...'.
                        webSocket sendMessage: message ] ] 
                on: ConnectionClosed 
                do: [ self crLog: 'Ignoring connection close, done' ]

If you select and execute the following part from the above

        ZnServer startDefaultOn: 1701.
        ZnServer default logToTranscript.
        ZnServer default delegate
                map: 'ws-test' 
                to: [ :request | ZnResponse ok: (ZnEntity html: 
ZnWebSocketDelegate wsTestHtml) ];
                map: 'ws-test-local' 
                to: [ :request | ZnResponse ok: (ZnEntity html: 
ZnWebSocketDelegate wsTestLocalHtml) ];
                map: 'ws-echo'
                to: (ZnWebSocketDelegate new 
                                prefixFromString: 'ws-echo'; 
                                handler: ZnWebSocketEchoHandler new; 
                                yourself).

You can use your browser to access the echo service through the standard 
JavaScript API

        http://localhost:1701/ws-test
        http://localhost:1701/ws-test-local

The first URL goes out to websocket.org, the second uses the local Zinc 
implementation.

Again, this is early code, anything might change.

So, if you have some prior knowledge in this area and are interested, have a 
look and let me know what you think.

Thx,

Sven


--
Sven Van Caekenberghe
http://stfx.eu
Smalltalk is the Red Pill





Reply via email to