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 ()
}