Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Websockets #1322

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ baseline: spec
self baselinefilesystem: spec.
self baselineadaptors: spec.
self baselinecomet: spec.
self baselinewebsocket: spec.
self baselinejavascript: spec.
self baselinejquery: spec.
self baselinejqueryui: spec.
Original file line number Diff line number Diff line change
@@ -39,7 +39,15 @@ baselineadaptors: spec

spec
for: #pharo
do: [
do: [
spec
baseline: 'Zinc WebSockets'
with: [
spec
className: 'BaselineOfZincHTTPComponents';
loads: #('WebSocket');
repository: 'github://svenvc/zinc:master/repository' ].

spec
package: 'Seaside-Adaptors-Comanche' with: [ spec requires: #('KomHttpServerLight' 'Seaside-Core') ];
package: 'KomHttpServerLight' with: [ spec repository: 'http://www.smalltalkhub.com/mc/Seaside/KomHttpServer/main' ];
@@ -56,7 +64,8 @@ baselineadaptors: spec

spec
for: #gemstone
do: [ spec
do: [
spec
project: 'FastCGI Project'
with: [ spec
className: 'ConfigurationOfGsFastCGI';
Original file line number Diff line number Diff line change
@@ -15,8 +15,7 @@ baselinegettext: spec
with: [ spec requires: #('Seaside-Gettext-Examples') ].
spec
group: 'Seaside-Gettext' with: #('Seaside-Gettext-Core');
group: 'Gettext-Examples'
with: #('Seaside-Gettext' 'Seaside-Gettext-Examples');
group: 'Gettext-Examples' with: #('Seaside-Gettext' 'Seaside-Gettext-Examples');
group: 'Tests' with: #('Seaside-Tests-Gettext-Core' 'Gettext-Examples') ].

spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
baselines
baselinewebsocket: spec

spec for: #'pharo' do: [
spec blessing: #baseline.
spec
package: 'Seaside-WebSocket-Core' with: [
spec requires: #('Javascript-Core' 'Seaside-Canvas' ) ];
" package: 'Seaside-WebSocket-Tests-Core' with: [
spec requires: #('Javascript-Tests-Core' 'Seaside-WebSocket-Core' ) ];"
package: 'Seaside-WebSocket-Zinc' with:[
spec requires: #('Zinc' 'Zinc WebSockets') ];
package: 'Seaside-WebSocket-Examples' with: [
spec requires: #('JQuery-Core' 'Seaside-WebSocket-Core') ].

spec
group: 'WebSocket' with: #('Seaside-WebSocket-Core' 'Seaside-WebSocket-Zinc');
" group: 'WebSocket Tests' with: #('Seaside-WebSocket-Tests-Core' );"
group: 'Examples' with: #('Seaside-WebSocket-Examples' )
"group: 'Tests' with: #('WebSocket Tests')" ]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
handling
handleFiltered: aRequestContext
"Handle aRequestContext by either dispatching to a different request handler of by producing a response and singalling the result."
"Handle aRequestContext by either dispatching to a different request handler of by producing a response and signalling the result."

self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
*Seaside-Tests-Pharo-Core
runCase
GRPlatform current doSilently: [ super performTest ]
GRPlatform current doSilently: [ super runCase ]
5 changes: 5 additions & 0 deletions repository/Seaside-WebSocket-Core.package/.filetree
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"separateMethodMetaAndSource" : false,
"noMethodMetaData" : true,
"useCypressPropertiesFile" : true
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
configuration
headerField
^ '_ws'
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
initialize-release
close
self call: 'close'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
printing
defaultUrl
^ self renderContext actionUrl
addField: self class headerField
value: self pusher id
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
accessing
filter
^ self session filters
detect: [ :each | each isWebSocketFilter ]
ifNone: [ self session addFilterFirst: WAWebSocketFilter new ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
printing
javascriptContentOn: aStream
"TODO: window.location should not be retrieved here..."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use #baseUrl or something similar here instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. It should probably use the settings of WARequestHandlingConfiguration... it's just that I do not prefer that way of working. Alas, I see no alternative either.

aStream
nextPutAll: 'new WebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + ';
javascript: self url;
nextPut: $).
pusher ifNotNil:[ pusher websocketEventHandlerJavaScriptOn: aStream ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
accessing
pusher: aPusher
self url: (self renderContext actionUrl
withField: self class headerField
value: (self filter
registerPusher: (pusher := aPusher)
context: self requestContext))
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
accessing
pusher
^ pusher
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
initialize-release
send: anObject
self call: 'send' with: anObject
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
accessing
url: aUrl
url := aUrl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
printing
url
^ url ifNil: [ url := self defaultUrl ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"commentStamp" : "",
"super" : "JSObject",
"category" : "Seaside-WebSocket-Core",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [
"pusher",
"url"
],
"name" : "JSWebSocket",
"type" : "normal"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*Seaside-WebSocket-Core
websocket
^ (JSWebSocket context: self context)
rendererClass: self species;
yourself
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "WARenderer"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*Seaside-WebSocket-Core
isWebSocketSetupRequest
"Return true when request can be considered a valid WebSocket setup request"

^ self isGet
and: [ (self headerAt: 'upgrade' ifAbsent: [ ^ false ]) asLowercase = 'websocket'
and: [ (self headerAt: 'connection' ifAbsent: [ ^ false ]) asLowercase = 'upgrade'
and: [ (self headerAt: 'sec-websocket-version' ifAbsent: [ ^ false ]) = '13'
and: [ self headers includesKey: 'sec-websocket-key' ] ] ] ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "WARequest"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*seaside-websocket-core
createWebSocket
self webSocket ifNotNil:[ Error signal: 'WAWebSocket already created' ].
^ self properties at: #webSocket put: (self webSocketCreator newWebSocketInRequestContext: self)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*seaside-websocket-core
webSocket
^ self properties at: #webSocket ifAbsent:[ nil ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*seaside-websocket-core
webSocketCreator: aWebSocketCreator
self properties at: #webSocketCreator put: aWebSocketCreator
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*seaside-websocket-core
webSocketCreator
^ self properties at: #webSocketCreator
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "WARequestContext"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*Seaside-WebSocket-Core
isWebSocketFilter
^ false
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "WARequestFilter"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am a WebSocket.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More an abstract class with server specific implementations.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
initialization
initializeWithRequestContext: aRequestContext

self initialize.
session := aRequestContext session.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
testing
isConnected

self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
callbacks
onClose: aBlock

onClose := aBlock
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
callbacks
onError: aOneArgumentBlock

onError := aOneArgumentBlock

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
callbacks
onMessage: aOneArgumentBlock

onMessage := aOneArgumentBlock
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
running
run
"Run the WebSocket's input process."

self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
callbacks
send: aString
"Write data to the socket"

self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
callbacks
timeout: seconds
"Sets the underlying stream timeout."
self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
private
touchSession
"Prevent session expiry."

session ifNotNil: [ :s |
Transcript show:'Touch session ', s key;cr.
s application cache at: s key ifAbsent:[ ] ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"commentStamp" : "<historical>",
"super" : "WAObject",
"category" : "Seaside-WebSocket-Core",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [
"session",
"onMessage",
"onClose",
"onError"
],
"name" : "WAWebSocket",
"type" : "normal"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I create new instances of WebSocket. I abstract away the server specific ways to create new WebSockets.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
instance creation
newWebSocketInRequestContext: aRequestContext
^ self socketClass basicNew initializeWithRequestContext: aRequestContext
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
instance creation
socketClass
self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"commentStamp" : "<historical>",
"super" : "WAObject",
"category" : "Seaside-WebSocket-Core",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [ ],
"name" : "WAWebSocketCreator",
"type" : "normal"
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
processing
createWebSocketForContext: aRequestContext
| webSocket |
webSocket := aRequestContext createWebSocket.
(pushers
at: (aRequestContext request fields
at: JSWebSocket headerField
ifAbsent: [ ^ nil ]))
addSocket: webSocket.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
processing
handleFiltered: aRequestContext
(aRequestContext request isWebSocketSetupRequest)
ifFalse: [ ^ super handleFiltered: aRequestContext ].

self createWebSocketForContext: aRequestContext.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
initialization
initialize
super initialize.
pushers := Dictionary new
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
testing
isWebSocketFilter
^ true
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
public
registerPusher: aPusher context: aContext
pushers at: aPusher id put: aPusher.
^ aPusher id
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"commentStamp" : "",
"super" : "WARequestFilter",
"category" : "Seaside-WebSocket-Core",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [
"pushers"
],
"name" : "WAWebSocketFilter",
"type" : "normal"
}
Empty file.
Loading