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?
Just wondering... Rob _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
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®, 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®, 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! ! _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
Janko Mivšek wrote:
> 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. better even SocketStream, although not sure how portable that is. Michael _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
In reply to this post by Janko Mivšek
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 <[hidden email]> wrote: Hi Rob, _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
In reply to this post by Janko Mivšek
On Tue, Sep 23, 2008 at 1:38 PM, Janko Mivšek <[hidden email]> wrote: 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 managed to get this into Squeak, with a little pretty-print help to fix up the missing linefeeds! Now I just have to learn how to actually read from the Socket, since the tests die during
stream := self socket accept underlyingSocket readStream binary. in acceptConnection
| stream | stream := self socket accept underlyingSocket readStream binary.
self receiveContentFrom: stream. self parseContent. self postReceiveAction.
stream close. since squeak has no Socket>>readStream method, which is apparently what the underlyingSocket is in Squeak!
I see why Michael said "better even SocketStream," though I don't know how to use that either! Thanks...I at least know what to try to figure out now... Rob _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
Free forum by Nabble | Edit this page |