簡體   English   中英

從FileEvent處理程序處理非全局變量

[英]Manipulate non-global variables from fileevent handler

有沒有一種方法可以從FileEvent處理程序中處理非全局變量? 考慮以下最小服務器:

proc initState {stateName} {
    upvar $stateName state
    set state(foo) bar
    set state(baz) bla
    # ...
    return
}

proc handleConnection {stateName newsock clientAddress clientPort} {
    upvar $stateName state
    fconfigure $newsock -blocking 0
    fconfigure $newsock -buffering line
    fileevent $newsock readable [list handleData $newsock]
    return
}

proc handleData {f} {
    if {[eof $f]} {
        fileevent $f readable {}
        close $f
        return
    }
    gets $f line
    puts $f ok
    # need to modify state here...
    return
}

proc runServer {port} {
    array set state {}
    initState state
    socket -server {handleConnection state} $port
    vwait forever
}

runServer 1234

是否有可能操縱在runServer范圍內創建的state數組,還是使state成為全局變量的唯一方法?

我對Tcl還是很陌生,如果我使用CI會簡單地將state指針傳遞到事件處理程序中,但不幸的是Tcl不允許這樣做。 我在這里做任何奇怪的事情,還有更多類似Tcl的方法嗎?

那根本行不通。 問題是Tcl的堆棧幀無法按照您所需的方式持久保存。

解決此問題的標准選項是:

  1. 將狀態保存在由“連接令牌”(例如,通道名稱)索引的全局數組中。 請記住,數組是由字符串索引的; 諸如“ sock42,hostname ”之類的復合鍵非常合法。

  2. 將狀態保留在以連接令牌命名的命名空間中 如果您使用的是Tcl 8.5,則可以使用namespace upvar命令輕松得多

  3. 將狀態保存在TclOO 對象中 (需要Tcl 8.6 8.5單獨的TclOO軟件包)或使用其他對象系統(例如[incr Tcl],XOTcl;這些可用於許多Tcl版本)。

  4. 將狀態保持在協程中 (需要Tcl 8.6)。 這有效地為您提供了一個命名堆棧(並允許您編寫代碼,因此它顯然是“直線”而不是由回調驅動),但是其版本要求非常嚴格

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM