package main import ( "fmt" "os" "golang.org/x/net/websocket" "net/http" "sync" "time" "log" ) type Client struct { mu sync.Mutex conn []*Conn } type Conn struct { conn *websocket.Conn //客户端链接 timeStamp int64 //加入时间 } var Clients Client func init() { Clients = Client{} //定时发送数据 // c := cron.New() // c.AddFunc("0/10 * * * * ?", func() { // fmt.Println("定时器") // for _,client := range Clients.conn{ // client.conn.Write([]byte("this is a check")) // } // }) // c.Start() } //错误处理函数 func checkErr(err error, extra string) bool { if err != nil { formatStr := " Err : %s\n" if extra != "" { formatStr = extra + formatStr } fmt.Fprintf(os.Stderr, formatStr, err.Error()) return true } return false } func svrConnHandler(conn *websocket.Conn) { request := make([]byte, 128) //记录连接的客户端信息 Clients.mu.Lock() Clients.conn = append(Clients.conn, &Conn{ conn:conn, timeStamp:time.Now().Unix(), }) Clients.mu.Unlock() defer func(){ log.Println("移除事件触发") for index,val := range Clients.conn{ if val.conn == conn{ Clients.mu.Lock() Clients.conn = Clients.conn[index:index+1] } } conn.Close() }() for { readLen, err := conn.Read(request) if checkErr(err, "Read") { break } //socket被关闭了 if readLen == 0 { fmt.Println("Client connection close!") break } else { //request 可做口令 这里 输出接收到的信息 fmt.Println(string(request[:readLen])) //回执客户端 conn.Write([]byte("success")) } request = make([]byte, 128) } } func main() { http.Handle("/echo", websocket.Handler(svrConnHandler)) err := http.ListenAndServe(":6666", nil) checkErr(err, "ListenAndServe") fmt.Println("Func finish.")
}
//client
package main import ( "fmt" "golang.org/x/net/websocket" "os" "sync" ) var gLocker sync.Mutex //全局锁 var gCondition *sync.Cond //全局条件变量 var origin = "http://127.0.0.1:6666/" var url = "ws://127.0.0.1:6666/echo" //错误处理函数 func checkErr(err error, extra string) bool { if err != nil { formatStr := " Err : %s\n" if extra != "" { formatStr = extra + formatStr } fmt.Fprintf(os.Stderr, formatStr, err.Error()) return true } return false } //连接处理函数 func clientConnHandler(conn *websocket.Conn) { gLocker.Lock() defer gLocker.Unlock() defer conn.Close() request := make([]byte, 128) for { readLen, err := conn.Read(request) if checkErr(err, "Read") { gCondition.Signal() break } //socket被关闭了 if readLen == 0 { fmt.Println("Server connection close!") //条件变量同步通知 gCondition.Signal() break } else { //输出接收到的信息 fmt.Println(string(request[:readLen])) ////发送 //conn.Write([]byte("Hello !")) } request = make([]byte, 128) } } func main() { conn, err := websocket.Dial(url, "", origin) if checkErr(err, "Dial") { return } gLocker.Lock() gCondition = sync.NewCond(&gLocker) _, err = conn.Write([]byte("Hello !")) go clientConnHandler(conn) //主线程阻塞,等待Singal结束 for { //条件变量同步等待 gCondition.Wait() break } gLocker.Unlock() fmt.Println("Client finish.") }