Changeset 1273 for trunk/p2p/server.tcl


Ignore:
Timestamp:
Feb 5, 2009, 6:17:23 AM (16 years ago)
Author:
mmc
Message:

Major reorganization of p2p code, and support for solicit/proffer
messages.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/p2p/server.tcl

    r1257 r1273  
    1111package require Itcl
    1212
     13namespace eval p2p { # forward declaration }
     14
     15# ======================================================================
     16#  USAGE: p2p::server ?-option value -option value ...?
     17#
     18#  Used to create a new peer-to-peer server object for this program.
     19#  Recognizes the following options:
     20#    -port ........ port number that the server listens on
     21#    -protocols ... list of protocol root names that the server handles
     22#               ... any other option supported by Server class
     23# ======================================================================
     24proc p2p::server {args} {
     25    set port "?"
     26    set protocols ""
     27    set options ""
     28    foreach {key val} $args {
     29        switch -- $key {
     30            -port { set port $val }
     31            -protocols { set protocols $val }
     32            default { lappend options $key $val }
     33        }
     34    }
     35
     36    if {[llength $protocols] == 0} {
     37        error "server needs at least one value for -protocols"
     38    }
     39
     40    # create the server
     41    set server [eval Server ::#auto $port $options]
     42
     43    # install the protocols that this server recognizes
     44    foreach name $protocols {
     45        p2p::protocol::init $server $name
     46    }
     47    return $server
     48}
     49
     50# ======================================================================
     51#  CLASS: Server
     52# ======================================================================
    1353itcl::class Server {
    1454    inherit Handler
     
    2464    # this code fragment gets invoked when client declares the protocol
    2565    public variable onprotocol ""
     66
     67    # this code fragment gets invoked when client drops
     68    public variable ondisconnect ""
    2669
    2770    constructor {port args} {
     
    59102
    60103    public method port {}
     104    public method broadcast {args}
    61105    public method connectionSpeaks {cid protocol}
    62106
     107    protected method dropped {cid}
    63108    protected method handlerType {}
    64109
     
    80125
    81126# ----------------------------------------------------------------------
     127#  USAGE: broadcast ?-protocol <name>? ?-avoid <avoidList>? <message>
     128#
     129#  Sends a <message> to all clients connected to this server.  If a
     130#  client address appears on the -avoid list, then that client is
     131#  avoided.  If the -protocol is specified, then the message is sent
     132#  only to clients who match the glob-style pattern for the protocol
     133#  name.
     134# ----------------------------------------------------------------------
     135itcl::body Server::broadcast {args} {
     136    set pattern "*"
     137    set avoidList ""
     138    set i 0
     139    while {$i < [llength $args]} {
     140        set option [lindex $args $i]
     141        if {[string index $option 0] == "-"} {
     142            switch -- $option {
     143                -protocol {
     144                    set pattern [lindex $args [expr {$i+1}]]
     145                    incr i 2
     146                }
     147                -avoid {
     148                    set avoidList [lindex $args [expr {$i+1}]]
     149                    incr i 2
     150                }
     151                -- {
     152                    incr i
     153                    break
     154                }
     155                default {
     156                    error "bad option \"$option\": should be -avoid, -protocol, or --"
     157                }
     158            }
     159        } else {
     160            break
     161        }
     162    }
     163    if {$i != [llength $args]-1} {
     164        error "wrong # args: should be \"broadcast ?-protocol pattern? ?-avoid clients? message\""
     165    }
     166    set message [lindex $args end]
     167
     168    set nmesgs 0
     169    foreach cid [connections $pattern] {
     170        set addr [lindex [connectionName $cid] 0]  ;# x.x.x.x (sockN)
     171        if {[llength $avoidList] == 0 || [lsearch $avoidList $addr] < 0} {
     172puts "  inbound => [connectionName $cid]"
     173            if {[catch {puts $cid $message} result] == 0} {
     174                incr nmesgs
     175            } else {
     176                log error "ERROR: broadcast failed for $cid: $result"
     177                log error "  (message was $message)"
     178            }
     179        }
     180    }
     181    return $nmesgs
     182}
     183
     184# ----------------------------------------------------------------------
    82185#  USAGE: accept <cid> <addr> <port>
    83186#
     
    116219
    117220# ----------------------------------------------------------------------
     221#  USAGE: dropped <cid>
     222#
     223#  Invoked automatically whenever a client connection drops, to
     224#  log the event and remove all trace of the client.  Invokes any
     225#  command hook for this server to note the fact that the client
     226#  has dropped.
     227# ----------------------------------------------------------------------
     228itcl::body Server::dropped {cid} {
     229    # if there's a callback to handle the drop, execute it here
     230    if {[string length $ondisconnect] > 0} {
     231        uplevel #0 [list $ondisconnect [connectionName $cid]]
     232    }
     233
     234    # call the base class method to clean up after the client
     235    chain $cid
     236}
     237
     238# ----------------------------------------------------------------------
    118239#  USAGE: handlerType
    119240#
Note: See TracChangeset for help on using the changeset viewer.