[Xotcl] object method as (fileevent) callback

Gustaf Neumann neumann at wu.ac.at
Sat Feb 4 17:33:52 CET 2023


Dear Vladimir,

On 01.02.23 19:47, Vladimir wrote:
> Sorry for ugly formatting. I do not know what is happened. Source of example in attachment.

The formatting was not so bad, but the yellow markup was missing.
Below is an implementation of the logic of your echo server in nx.

The callback methods have to be public, since these are called from the 
Tcl event loop, i.e. outside of the server object scope. Therefore the 
callback methods "accept" and "echo" are required to be public.

Probably, it would be possible to implement a variant of ":callback 
"without this
requirement, using some internal nsf magic, but i am not sure this would 
be good.

Hope this helps!

-gn

======================================================================
#!/usr/bin/env tclsh
package require nx::trait

namespace eval ::proj {
  
     nx::Class create Server {
         set :version 0.1

         :property port:integer
         :require trait nx::trait::callback

         :method log {msg} {
             puts stderr "[namespace current]::Server ([self]): $msg"
         }
         
         :method init {} {
             :log "Init mock Server [set [current class]::version]"
             set :listen [socket -server [:callback accept] ${:port}]
         }

         :method destroy {} {
             close ${:listen}
             next
         }

         :public method accept {sock addr localport} {
             :log "accept $sock $addr $localport"
             fconfigure $sock -translation binary -buffering none
             fileevent $sock readable [:callback echo $sock]
         }

         :public method echo {sock} {
             :log "... $sock echo"
             if { [eof $sock] } {
                 close $sock
                 :log "... $sock close"
             } else {
                 set binary_msg [read $sock 2]
                 binary scan $binary_msg "H*" string_msg
                 :log "... $sock read 2 bytes 0x$string_msg"
                 if {[string length $string_msg] > 0} {
                     :log "... $sock echo"
                     puts -nonewline $sock $binary_msg
                 }
             }
         }
     }
}

set s [proj::Server new -port 1950]
vwait forever
======================================================================


More information about the Xotcl mailing list