首页 > 开发 > 综合 > 正文

一个SDK里做聊天室的例子(1)

2024-07-21 02:21:59
字体:
来源:转载
供稿:网友
option explicit on
option strict on

imports system
imports system.io
imports system.text
imports system.threading
imports system.net
imports system.net.sockets
imports system.drawing
imports system.windows.forms
imports microsoft.visualbasic



class app
    
    'entry point which delegates to c-style main private function
    public overloads shared sub main()
        main(system.environment.getcommandlineargs())
    end sub
    
    ' entry point
    overloads public shared sub main(args() as string)
        ' if the args parse in known way then run the app
        if parseargs(args) then
            ' create a custom talker object
            dim talkerobj as new talker(endpoint, client)
            ' pass the object reference to a new form object
            dim form as new talkform(talkerobj)
            ' start the talker "talking"
            talkerobj.start()
            
            ' run the applications message pump
            application.run(form)
        end if
    end sub 'main
    
    ' parsed argument storage
    private shared endpoint as ipendpoint
    private shared client as boolean
    
    
    ' parse command line arguments
    private shared function parseargs(args() as string) as boolean
        try
            if args.length = 1 then
                client = false
                endpoint = new ipendpoint(ipaddress.any, 5150)
                return true
            end if
           
            dim port as integer
            select case char.toupper(args(1).tochararray()(1))
                case "l"c
                    port = 5150
                    if args.length > 2 then
                        port = convert.toint32(args(2))
                    end if
                    endpoint = new ipendpoint(ipaddress.any, port)
                    client = false
                case "c"c
                    port = 5150
                    dim address as string = "127.0.0.1"
                    client = true
                    if args.length > 2 then
                        address = args(2)
                        port = convert.toint32(args(3))
                    end if
                    endpoint = new ipendpoint(dns.resolve(address).addresslist(0), port)
                case else
                    showusage()
                        return false
            end select
        catch
        end try
        
        return true
    end function 'parseargs
    
    
    ' show sample usage
    private shared sub showusage()
        messagebox.show("wintalk [switch] [parameters...]" & controlchars.crlf & controlchars.crlf & _
            "  /l  [port]" & controlchars.tab & controlchars.tab & "-- listens on a port.  default:  5150" & controlchars.crlf & _
            "  /c  [address] [port]" & controlchars.tab & "-- connects to an address and port." & controlchars.crlf & controlchars.crlf & _
            "example server - " & controlchars.crlf & _
            "wintalk /l" & controlchars.crlf & controlchars.crlf & _
            "example client - " & controlchars.crlf & _
            "wintalk /c servermachine 5150", "wintalk usage")
    end sub 'showusage
end class 'app


' ui class for the sample
class talkform
    inherits form
    
    public sub new(talkerobj as talker)
        ' associate for method with the talker object
        me.talkerobj = talkerobj
        addhandler talkerobj.notifications, addressof handletalkernotifications
        
        ' create a ui elements
        dim talksplitter as new splitter()
        dim talkpanel as new panel()

        receivetext = new textbox()
        sendtext = new textbox()
        
        'we'll support up to 64k data in our text box controls
        receivetext.maxlength = 65536
        sendtext.maxlength = 65536
        
        statustext = new label()
        
        ' initialize ui elements
        receivetext.dock = dockstyle.top
        receivetext.multiline = true
        receivetext.scrollbars = scrollbars.both
        receivetext.size = new size(506, 192)
        receivetext.tabindex = 1
        receivetext.text = ""
        receivetext.wordwrap = false
        receivetext.readonly = true
        
        talkpanel.anchor = anchorstyles.top or anchorstyles.bottom or anchorstyles.left or anchorstyles.right
        talkpanel.controls.addrange(new control() {sendtext, talksplitter, receivetext})
        talkpanel.size = new size(506, 371)
        talkpanel.tabindex = 0
        
        talksplitter.dock = dockstyle.top
        talksplitter.location = new point(0, 192)
        talksplitter.size = new size(506, 6)
        talksplitter.tabindex = 2
        talksplitter.tabstop = false
        
        statustext.dock = dockstyle.bottom
        statustext.location = new point(0, 377)
        statustext.size = new size(507, 15)
        statustext.tabindex = 1
        statustext.text = "status:"
        
        sendtext.dock = dockstyle.fill
        sendtext.location = new point(0, 198)
        sendtext.multiline = true
        sendtext.scrollbars = scrollbars.both
        sendtext.size = new size(506, 173)
        sendtext.tabindex = 0
        sendtext.text = ""
        sendtext.wordwrap = false
        addhandler sendtext.textchanged, addressof handletextchange
        sendtext.enabled = false
        
        autoscalebasesize = new size(5, 13)
        clientsize = new size(507, 392)
        controls.addrange(new control() {statustext, talkpanel})
        me.text = "wintalk"

        me.activecontrol = sendtext
    end sub 'new
    
    
    ' when the app closes, dispose of the talker object
    protected overrides sub onclosed(e as eventargs)
        if not (talkerobj is nothing) then
            removehandler talkerobj.notifications, addressof handletalkernotifications
            talkerobj.dispose()
        end if
        mybase.onclosed(e)
    end sub 'onclosed
    
    
    ' handle notifications from the talker object
    private sub handletalkernotifications(notify as talker.notification, data as object)
        select case notify
            case talker.notification.initialized
                ' respond to status changes
            case talker.notification.statuschange
                dim statusobj as talker.status = ctype(data, talker.status)
                statustext.text = string.format("status: {0}", statusobj)
                if statusobj = talker.status.connected then
                    sendtext.enabled = true
                end if
                ' respond to received text
            case talker.notification.received
                receivetext.text = data.tostring()
                receivetext.selectionstart = int32.maxvalue
                receivetext.scrolltocaret()
                ' respond to error notifications
            case talker.notification.errornotify
                close(data.tostring())
                ' respond to end
            case talker.notification.endnotify
                messagebox.show(data.tostring(), "closing wintalk")
                close()
            case else
                close()
        end select
    end sub 'handletalkernotifications
    
    
    ' handle text change notifications and send talk
    private sub handletextchange(sender as object, e as eventargs)
        if not (talkerobj is nothing) then
            talkerobj.sendtalk(ctype(sender, textbox).text)
        end if
    end sub 'handletextchange
    
    
    ' close with an explanation
    private overloads sub close(message as string)
        messagebox.show(message, "error!")
        close()
    end sub 'close
    
    ' private ui elements
    private receivetext as textbox
    private sendtext as textbox
    private statustext as label
    private talkerobj as talker

    private sub talkform_load(byval sender as system.object, byval e as system.eventargs) handles mybase.load

    end sub

    private sub initializecomponent()
        '
        'talkform
        '
        me.autoscalebasesize = new system.drawing.size(6, 14)
        me.clientsize = new system.drawing.size(292, 273)
        me.name = "talkform"

    end sub
end class 'talkform


' an encapsulation of the sockets class used for socket chatting
class talker
    implements idisposable
    
    ' construct a talker
    public sub new(endpoint as ipendpoint, client as boolean)
        me.endpoint = endpoint
        me.client = client
        
        socket = nothing
        reader = nothing
        writer = nothing
        
        statustext = string.empty
        prevsendtext = string.empty
        prevreceivetext = string.empty
    end sub 'new
    
    
    ' finalize a talker
    overrides protected sub finalize()
        dispose()
        mybase.finalize()
    end sub 'finalize
    
    
    ' dispose of resources and surpress finalization
    public sub dispose() implements idisposable.dispose
        gc.suppressfinalize(me)
        if not (reader is nothing) then
            reader.close()
            reader = nothing
        end if
        if not (writer is nothing) then
            writer.close()
            writer = nothing
        end if
        if not (socket is nothing) then
            socket.close()
            socket = nothing
        end if
    end sub 'dispose
    
    
    ' nested delegate class and matchine event
    delegate sub notificationcallback(notify as notification, data as object)
    public event notifications as notificationcallback
    
    
    ' nested enum for notifications
    public enum notification
        initialized = 1
        statuschange
        received
        endnotify
        errornotify
    end enum 'notification
 
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表