Hello,
following up on my previous question and the [fconfigure -blocking 0]
issue with sockets.
I did now rewrite my code to make it more bullet proof and also try to
use [fileevent writable]. The relevant parts look like the code below.
Essentially I set up a writable event, which consumes every message in a
_Queue (a list variable) and puts it on the socket, when the socket is
writable. Sending to the socket does only [lappend] the message on the
_Queue, from which it is consumed in the writable event.
Now I recognized that this event is fired very often, which hurts some
other parts of my application. Also I read in the [puts] manual that
[puts] does apparently keep an internal buffer and puts the message on
the underlying socket just as soon as this is possible - the last
section starting with "When the output buffer fills up..." here:
http://tcl.tk/man/tcl8.6/TclCmd/puts.htm
So my question is: is it at all necessary to self implement a message
queue and consume it via a [fileevent writable]? Can strange things
happen in border conditions, if I leave that part out and do [puts $sock
...] directly?
And if it is not necessary, what is [fileevent writable] good for at
all, except checking if the socket is connected, when in -async mode?
proc connect {port} {
global _Connected
set sock [socket -async localhost $port]
fconfigure $Socket -translation auto -buffering line -blocking 0
fileevent $sock writable [list connectionEstablished $sock]
vwait _Connected
if {$_Connected ne "success"} {
throw {MY ERR} "connection cannot be established: $_Connected"
}
unset _Connected
}
proc connectionEstablished {sock} {
global _Connected
fileevent $sock writable {}
set err [fconfigure $sock -error]
if {$err != {}} {
set _Connected $err
return
}
fileevent $sock readable [list handleRead $sock]
fileevent $sock writable [list handleWrite $sock]
set _Connected success
}
proc handleWrite {sock} {
global _Queue
while {[info exists _Queue] && ![fblocked $sock] && $_Queue != {}} {
set msg [lindex $_Queue 0]
puts $sock $msg
set _Queue [lrange $_Queue 1 end]
}
}
proc handleRead {sock} {
...
}
proc send {sock msg} {
global _Queue
lappend _Queue $msg
}
set s [connect 1234]
send $s "Hello World"
--
EL