[aida] Swazoo Client/Server?

Rob Rothwell r.j.rothwell at gmail.com
Tue Sep 23 22:31:24 CEST 2008


Thank you!
We will just be passing a patient account number and getting back a text
stream of some sort suitable for display.

I figured it was Sockets, but so many other things are so easy, that I
thought I'd ask before writing my own message protocol!

Thanks again,

Rob

On Tue, Sep 23, 2008 at 1:38 PM, Janko Mivšek <janko.mivsek at eranova.si>wrote:

> Hi Rob,
>
> Rob Rothwell wrote:
>
>> We are writing a little utility using Squeak as a processing server on the
>> network, and a VB tray application as a client.
>>
>> Should I jump right into Sockets in Squeak, or is there something that can
>> be done at a "higher" level using Swazoo to listen for a message and send
>> back a result?
>>
>
> It depends a lot of your app. But if there is not a HTTP protocol involved,
> you better go with sockets directly. I propose that you get used of Sport's
> SpSocket, to be safely portable in the future.
>
> I attached such a little server I made recently, named LineTCPConnect and
> this is kind of Swazoo lite. This is a fileout from VW and should be easily
> imported to Squeak. Just Word menu>Open>File list, find .st, right click and
> "remove line feeds" then "code-file browser"...
>
> Janko
>
> --
> Janko Mivšek
> AIDA/Web
> Smalltalk Web Application Server
> http://www.aidaweb.si
>
> 'From VisualWorks(R), 7.4.1 of May 30, 2006 on September 23, 2008 at 7:31:07
> pm'!
>
>
> Object subclass: #LineTCPConnect
>        instanceVariableNames: 'parent port socket loop content headers body
> '
>        classVariableNames: ''
>        poolDictionaries: ''
>        category: 'BiArt-Core'!
>
> LineTCPConnect class
>        instanceVariableNames: ''!
>
> "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
>
>
> !LineTCPConnect class methodsFor: 'instance creation' stamp: ' 23/9/08
> 19:31'!
>
> newFor: anAIDASite
>        ^self new parent: anAIDASite! !
>
> !LineTCPConnect class methodsFor: 'defaults' stamp: ' 23/9/08 19:31'!
>
> defaultPort
>        ^8870! !
>
> "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
>
>
> LineTCPConnect comment:
> 'LineTCPConnect is a TCP server listening for connections from flowmeter
> measuring line sending measurenment data and documents.'!
>
> !LineTCPConnect methodsFor: 'accessing' stamp: ' 23/9/08 19:31'!
>
> body
>        ^body!
>
> body: aString
>        body := aString!
>
> content
>        "received content"
>        ^content!
>
> content: aByteArray
>        content := aByteArray!
>
> headers
>        headers isNil ifTrue: [self initHeaders].
>        ^headers!
>
> loop
>        ^loop!
>
> loop: aProcess
>        loop := aProcess!
>
> parent
>        ^parent!
>
> parent: anAIDASite
>        parent := anAIDASite!
>
> port
>        port isNil ifTrue: [self port: self class defaultPort].
>        ^port!
>
> port: aNumber
>        port := aNumber!
>
> socket
>        ^socket!
>
> socket: aSpSocket
>        socket := aSpSocket! !
>
> !LineTCPConnect methodsFor: 'start/stop' stamp: ' 23/9/08 19:31'!
>
> start
>        self loop notNil ifTrue: [self stop].
>        self socket: SpSocket newTCPSocket.
>        self socket
>                setAddressReuse: true;
>                bindSocketAddress: (SpIPAddress hostName: '0.0.0.0' port:
> self port).
>        self socket listenBackloggingUpTo: 10.
>        self loop: ([[self acceptConnection] repeat] fork)!
>
> stop
>        self loop notNil ifTrue:
>                [self loop terminate. self loop: nil].
>        self socket notNil ifTrue:
>                [self socket close. self socket: nil].! !
>
> !LineTCPConnect methodsFor: 'private-receiving' stamp: ' 23/9/08 19:31'!
>
> acceptConnection
>        | stream |
>        stream  := self socket accept underlyingSocket readStream binary.
>        self receiveContentFrom: stream.
>        self parseContent.
>        self postReceiveAction.
>        stream close.!
>
> postReceiveAction
>        "do whatever appropriate with a received content"
>        Transcript cr; show: 'received ', self content size printString, '
> bytes'.
>        self parent isNil ifTrue: [^nil]. "for testing purposes"
>        self headers size >= 2 ifFalse: [^nil].
>        self parent calibrations
>                attachAndCloseFlowMeterMeasurementFile: self headers first
> key
>                content: self body
>                measuredBy: (AIDASite convert: self headers second key
> fromCodepage: #UTF8)
>                tempAverage: (self valueForHeader: 'Tokolice')
>                tempDifference: (self valueForHeader: 'DeltaTokolice')
>                atmosphericPressure: (self valueForHeader: 'AtmTlak')
>                counterAtEnd: (self valueForHeader: 'Stanje')!
>
> receiveContentFrom: aStream
>        "until peer close a socket,  put it in content instvar"
>        | stream |
>        stream := WriteStream on: ByteString new.
>        [[aStream atEnd] whileFalse:
>                [stream nextPut: aStream next asCharacter] ]
>                        on: Error
>                        do: [:ex | ].
>        self content: stream contents! !
>
> !LineTCPConnect methodsFor: 'initialize-release' stamp: ' 23/9/08 19:31'!
>
> initHeaders
>        headers := OrderedCollection new! !
>
> !LineTCPConnect methodsFor: 'private-parsing' stamp: ' 23/9/08 19:31'!
>
> parseContent
>        | stream |
>        stream := self content readStream.
>        self readHeadersFrom: stream.
>        self readBodyFrom: stream.!
>
> readBodyFrom: aStream
>        self body: aStream upToEnd!
>
> readHeadersFrom: aStream
>        | line assoc |
>        self initHeaders.
>        [aStream atEnd] whileFalse:
>                [line := aStream upTo: Character cr. aStream next. "skip lf"
>                assoc := Association new.
>                assoc key: (line readStream upTo: $:).
>                assoc value: (line readStream upTo: $: ; upToEnd)
> trimBlanks.
>                self headers add: assoc.
>                aStream peek = Character cr ifTrue:
>                        [aStream next; next. "skip crl lf"
>                        ^self headers].
>                ]!
>
> valueForHeader: aString
>        "value from headers with that name"
>        " 'DeltaTokolice 0.69700'->'' "
>        | header |
>        header := self headers detect: [:each | (aString, '*') match: each
> key] ifNone: [^nil].
>        ^((header key readStream upToSeparator; upToEnd) copyReplaceAll: '.'
> with: ',')
>                asFixedPoint: 4! !
>
> 'From VisualWorks(R), 7.4.1 of May 30, 2006 on September 23, 2008 at 7:31:11
> pm'!
>
>
> TestCase subclass: #LineTCPConnectTest
>        instanceVariableNames: ''
>        classVariableNames: ''
>        poolDictionaries: ''
>        category: 'GeoMer-Tests'!
>
> LineTCPConnectTest class
>        instanceVariableNames: ''!
>
> !LineTCPConnectTest methodsFor: 'testing' stamp: ' 23/9/08 19:31'!
>
> testParsing
>        | connect client |
>        connect := LineTCPConnect new port: 5678. "to be different than
> default"
>        connect start.
>        [client := SpSocket connectToServerOnHost: '0.0.0.0' port: connect
> port.
>        client write: self content.
>        client close. (Delay forMilliseconds: 100) wait.
>        ] ensure: [client close. connect stop].
>        connect parseContent.
>        self assert: connect headers first = ('file.dat'-> '').
>        self assert: connect headers last = ('content-length'-> self body
> size printString).
>        self assert: connect body = self body.!
>
> testSending
>        | connect client |
>        connect := LineTCPConnect new port: 5678. "to be different than
> default"
>        connect start.
>        [client := SpSocket connectToServerOnHost: '0.0.0.0' port: connect
> port.
>        client write: self content.
>        client close.
>        (Delay forMilliseconds: 100) wait.
>        self assert: connect content = self content.
>        ] ensure: [client close. connect stop].!
>
> testStartup
>        | connect |
>        connect := LineTCPConnect new.
>        connect start.
>        [self assert: connect socket notNil.
>        self assert: connect loop notNil]
>                ensure: [connect stop].
>        self assert: connect socket isNil.
>        self assert: connect loop isNil.! !
>
> !LineTCPConnectTest methodsFor: 'setup' stamp: ' 23/9/08 19:31'!
>
> body
>        ^'body of the message'.
> !
>
> content
>        ^'file.dat', self crlf,
>        'content-length: ', self body size printString, self crlf,
>        self crlf,
>        self body!
>
> crlf
>        ^String with: Character cr with: Character lf! !
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.aidaweb.si/pipermail/aida/attachments/20080923/6fa4ad8a/attachment-0001.htm 


More information about the Aida mailing list