added some experimental code

This commit is contained in:
hyunghwan.chung 2018-05-21 17:14:16 +00:00
parent f3fc35fc02
commit b42586a1c6
2 changed files with 279 additions and 2 deletions

View File

@ -269,6 +269,169 @@ class HttpServer(Object)
}
}
class HttpListener2(Socket)
{
var(#get) server := nil.
var(#get) rid := -1.
var sem.
method initialize
{
super initialize.
self.sem := Semaphore new.
self.sem signalAction: [:sem |
| cliaddr clisck cliact fd |
cliaddr := SocketAddress new.
fd := self _accept: cliaddr.
##if (fd >= 0)
if (fd notNil)
{
clisck := (self acceptedSocketClass) __with: fd.
clisck beWatched.
self onSocketAccepted: clisck from: cliaddr.
}.
].
}
(*
method onSocketAccepted: clisck from: cliaddr
{
| rid |
'CLIENT accepted ..............' dump.
clisck dump.
cliaddr dump.
if (self.server notNil)
{
server addConnection: clisck.
if (clisck isKindOf: SyncSocket)
{
'SERVICE READLLY STARTING' dump.
[clisck runService] fork.
}
}.
}
method acceptedSocketClass
{
##^if (self currentAddress port == 80) { HttpSocket } else { HttpSocket }.
^HttpSocket.
}
method server: server rid: rid
{
self.server := server.
self.rid := rid.
}
*)
}
class HttpServer2(Object)
{
var listeners.
var connreg.
var sg.
method initialize
{
super initialize.
self.sg := SemaphoreGroup new.
self.listeners := HttpConnReg new.
self.connreg := HttpConnReg new.
}
method run: laddr
{
| listener sem ss |
if (laddr class == Array)
{
laddr do: [:addr |
listener := HttpListener2 family: (addr family) type: Socket.Type.STREAM.
if ((self addListener: listener) notError)
{
listener bind: addr.
listener _listen: 128.
}
].
}
else
{
listener := HttpListener2 family: (laddr family) type: Socket.Type.STREAM.
if ((self addListener: listener) notError)
{
listener bind: laddr.
listener _listen: 128.
}
}.
while (true)
{
ss := self.sg wait.
if (ss isError) { break }.
}.
}
method close
{
self.listeners do: [:listener |
listener close.
].
self.connreg do: [:conn |
conn close.
].
}
method addConnection: conn
{
| rid |
rid := self.connreg add: conn.
if (rid isError)
{
'ERROR - CANNOT REGISTER NEW CONNECTION >>>>>>>>>> ' dump.
conn close.
^rid.
}.
('ADD NEW CONNECTION ' & rid asString) dump.
conn server: self rid: rid.
}
method removeConnection: conn
{
self.connreg remove: (conn rid).
conn server: nil rid: -1.
}
method addListener: listener
{
| rid |
rid := self.listeners add: listener.
if (rid isError)
{
'ERROR - CANNOT REGISTER NEW LISTENER >>>>>>>>>> ' dump.
listener close.
^rid.
}.
('ADD NEW LISTENER ' & rid asString) dump.
listener server: self rid: rid.
}
method removeListener: listener
{
self.listeners remove: (listener rid).
listener server: nil rid: -1.
}
}
class MyObject(Object)
{
method(#class) start_server_socket
@ -405,7 +568,7 @@ class MyObject(Object)
'----- END OF ANOTHER PROC ------' dump.
}
method(#class) main
method(#class) main222
{
| httpd addr |
@ -446,4 +609,24 @@ httpd connect: addr.
'----- END OF MAIN ------' dump.
}
method(#class) main
{
| httpd addr |
[
httpd := HttpServer2 new.
[
httpd run: %(
SocketAddress fromString: '[::]:7777',
SocketAddress fromString: '0.0.0.0:7776'
).
] ensure: [
if (httpd notNil) { httpd close }
]
] on: Exception do: [:ex | ('Exception - ' & ex messageText) dump].
'----- END OF MAIN ------' dump.
}
}

View File

@ -722,6 +722,100 @@ class AsyncServerSocket(AsyncSocket)
method acceptedSocketClass
{
^Socket
^AsyncSocket
}
}
class Mux(SemaphoreGroup)
{
method addSocket: sck
{
self addSemaphore: (sck inreadysem).
}
method removeSocket: sck
{
}
}
class ListenerSocket(Socket)
{
var inreadysem.
method initialize
{
'Server Socket initialize...........' dump.
super initialize.
self.inreadysem signalAction: [ :sem |
| cliaddr clisck cliact fd |
cliaddr := SocketAddress new.
fd := self _accept: cliaddr.
##if (fd >= 0)
if (fd notNil)
{
clisck := (self acceptedSocketClass) __with: fd.
sg addSemaphore: self.inreadysem.
self.inreadysem signalOnInput: self.handle.
self onSocketAccepted: clisck from: cliaddr.
}.
].
}
method close
{
'CLOSING SERVER SOCEKT.... ' dump.
| sg |
if (self.inreadysem notNil)
{
self.inreadysem unsignal.
sg := self.inreadysem _group.
if (sg notNil) { sg removeSemaphore: self.inreadysem }.
self.inreadysem := nil.
}.
^super close.
}
method listen: backlog
{
| n |
## If listen is called before the socket handle is
## added to the multiplexer, a spurious hangup event might
## be generated. At least, such behavior was observed
## in linux with epoll in the level trigger mode.
## self.inreadysem signalOnInput: self.handle.
## thisProcess addAsyncSemaphore: self.inreadysem.
## self _listen: backlog.
n := self _listen: backlog.
self.inreadysem signalOnInput: self.handle.
sg addemaphore: self.inreadysem.
^n.
}
method accept
{
}
method onSocketAccepted: clisck from: cliaddr
{
## close the accepted client socket immediately.
## a subclass must override this to avoid it.
clisck close.
}
method acceptedSocketClass
{
^Socket
}
}