Note that it is up to the caller to ensure that the current object is able to handle the call of methodName; this command does not check that. methodName may refer to any exported or unexported method, but may not refer to a private method as those can only be invoked directly from within methods. If there is no such method present at the point when the callback is invoked, the standard unknown method handler will be called.
oo::class create EchoServer {
variable server clients
constructor {port} {
set server [socket -server [callback Accept] $port]
set clients {}
}
destructor {
chan close $server
foreach client [dict keys $clients] {
chan close $client
}
}
method Accept {channel clientAddress clientPort} {
dict set clients $channel [dict create \
address $clientAddress port $clientPort]
chan event $channel readable [callback Receive $channel]
}
method Receive {channel} {
if {[chan gets $channel line] >= 0} {
my echo $channel $line
} else {
chan close $channel
dict unset clients $channel
}
}
method echo {channel line} {
dict with clients $channel {
chan puts $channel \
[format {[%s:%d] %s} $address $port $line]
}
}
}