Go Chat Code

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Main.go (server)


Package Main


Import (
"Git.letv.cn/uts/qpid-go_0_10/libqpid"
"./tbs"
"FMT"
"Time"
)

Func Main () {
var cb tbs. Eventcallback = OnTest
Get Dispatcher Singleton
Tbs. Setcallback (&CB)
Service: = ": 1200"
Tbs. serverstarted (Service)

Because the main thread does not wait for the child thread to close the process directly, this will not see the effect, so I added a blocking delay here
Time. Sleep (time. Second * 1)
}

Back up, we got an event object.
Func ontest (Event *tbs. Event) {
Fmt. Println ("OnTest", event. params["id"])
}


Tbs.go

Package TBS

Import (
"FMT"
"NET"
"OS"
"Time"
)

Type Dispatcher struct {
Listeners Map[string]*eventchain
}

Type Eventchain struct {
CHS []chan *event
Callbacks []*eventcallback
}

Func Createeventchain () *eventchain {
return &eventchain{chs: []chan *event{}, callbacks: []*eventcallback{}}
}

Type Event struct {
EventName string
Params map[string]interface{}
}

Func serverstarted (port string) {
Fmt. PRINTLN ("server started.")
TCPADDR, err: = Net. RESOLVETCPADDR ("TCP4", Port)
CheckError (ERR)
Listener, err: = Net. LISTENTCP ("TCP", TCPADDR)
for {
Conn, err: = Listener. Accept ()
If err! = Nil {
Continue
}
Go handleclient (conn)
}
}

Func handleclient (Conn net. Conn) {
Conn. Setreaddeadline (time. Now (). ADD (2 * time. Minute)//Set 2 minutes timeout
Request: = Make ([]byte, +)//Set Maxium request length to 128B to prevent flood attack
Defer Conn. Close ()//close connection before exit
for {
Read_len, ERR: = conn. Read (Request)

If err! = Nil {
Fmt. PRINTLN (ERR)
If Read_len = = 0 {
Remove Listener
Dispatcher: = Shareddispatcher ()
Dispatcher. RemoveEventListener ("Test", _CB)
}
Break
}
Fmt. PRINTLN ("message:")
Fmt. Println (string (Request))
If Read_len = = 0 {
Remove Listener
Dispatcher: = Shareddispatcher ()
Dispatcher. RemoveEventListener ("Test", _CB)
Break//connection already closed by client
} else {
OnData (Request)
}

Request = Make ([]byte, +)//clear last Read content
}
}

Func onData (Request []byte) {
To get a random argument, I define the parameter as a map.
Params: = Make (map[string]interface{})
params["id"] = 1000

Create an Event object
Event: = CreateEvent ("Test", params)
Event. params["bytes"] = Request

Get Dispatcher Singleton
Dispatcher: = Shareddispatcher ()

Add Listener
Dispatcher. AddEventListener ("Test", _CB)

Dispatch the event.
Dispatcher. Dispatchevent (Event)
}

Func checkerror (err error) {
If err! = Nil {
Fmt. fprintf (OS. Stderr, "Fatal Error:%s", err. Error ())
Os. Exit (1)
}
}

Func CreateEvent (EventName string, params map[string]interface{}) *event {
Return &event{eventname:eventname, Params:params}
}

Type eventcallback func (*event)
var _instance *dispatcher
var _CB *eventcallback

Func Setcallback (callback *eventcallback) {
_CB = Callback
}

Func Shareddispatcher () *dispatcher {
if _instance = = Nil {
_instance = &dispatcher{}
_instance. Init ()
}

Return _instance
}

Func (this *dispatcher) Init () {
This.listeners = Make (Map[string]*eventchain)
}

Func (this *dispatcher) AddEventListener (EventName string, callback *eventcallback) {
Eventchain, OK: = This.listeners[eventname]
If!ok {
Eventchain = Createeventchain ()
This.listeners[eventname] = Eventchain
}

exist: = False
For _, Item: = Range Eventchain.callbacks {
If Item = = Callback {
exist = True
Break
}
}

If exist {
Return
}

CH: = Make (chan *event)

Fmt. Printf ("Add Listener:%s\n", EventName)
Eventchain.chs = Append (eventchain.chs[:], CH)
Eventchain.callbacks = Append (eventchain.callbacks[:], callback)

Go func () {
for {
Event: = <-ch
If event = = Nil {
Break
}
(*callback) (event)
}
}()
}

Func (this *dispatcher) RemoveEventListener (EventName string, callback *eventcallback) {
Eventchain, OK: = This.listeners[eventname]
If!ok {
Return
}

var ch Chan *event
exist: = False
Key: = 0
For k, item: = Range Eventchain.callbacks {
If Item = = Callback {
exist = True
ch = eventchain.chs[k]
Key = K
Break
}
}

If exist {
Fmt. Printf ("Remove Listener:%s\n", EventName)
Ch <-Nil

Eventchain.chs = Append (Eventchain.chs[:key], eventchain.chs[key+1:] ...)
Eventchain.callbacks = Append (Eventchain.callbacks[:key], eventchain.callbacks[key+1:] ...)
}
}

Func (this *dispatcher) dispatchevent (event *event) {
Eventchain, OK: = This.listeners[event.eventname]
If OK {
Fmt. Printf ("Dispatch event:%s\n", Event.eventname)
For _, Chevent: = Range Eventchain.chs {
Chevent <-Event
}
}
}


Main.go (client)

Package Main

Import (
"Bufio"
"FMT"
"Log"
"NET"
"OS"
"Strings"
)

Connecting to a server
Func ConnectServer () {
Connected
Conn, Err: = Net. Dial ("TCP", "10.75.144.119:1200")
CheckError (ERR)
Fmt. PRINTLN ("Connection Successful! \ n ")
Input
Inputreader: = Bufio. Newreader (OS. Stdin)
Fmt. Println ("Who Are You?") ")
Name, _: = inputreader.readstring (' \ n ')
//
Trimname: = Strings. Trim (name, "\ r \ n")
Conn. Write ([]byte (trimname + "Access \ n"))
for {
Fmt. PRINTLN ("Let's Talk!" Press quit to exit ")
Read a line
Input, _: = inputreader.readstring (' \ n ')
Triminput: = Strings. Trim (input, "\ r \ n")
If quit quit,
if triminput = = "Quit" {
Fmt. Println ("Good-Bye")
Conn. Write ([]byte (Trimname + "exited"))
Return
}
Write it up.
_, Err = conn. Write ([]byte (trimname + "says" + triminput))
}
}

Check for errors
Func checkerror (err error) {
If err! = Nil {
Log. Fatal ("An error!", err. Error ())
}
}

Main function
Func Main () {
Connection Servser
ConnectServer ()
}




Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.