// Write received messages from a channel to the websocket client func FrameServer(conn *websocket.Conn) { // Set the PayloadType to binary conn.PayloadType = websocket.BinaryFrame client := NewClient() registerClient <- client defer func() { unregisterClient <- client }() // Write the header as the first message to the client (MPEG size etc.) conn.SetWriteDeadline(time.Now().Add(ClientWriteTimeout * time.Second)) if _, err := conn.Write(*headerMessage); err != nil { return } // Continuously read messages from the queue and write to the client, stop on error for msg := range client.queue { conn.SetWriteDeadline(time.Now().Add(ClientWriteTimeout * time.Second)) if _, err := conn.Write(*msg); err != nil { return } } }
func (endpoint *WebsocketEndpoint) Handle(ws *websocket.Conn) { ws.PayloadType = websocket.BinaryFrame var buf = make([]byte, 1024*64) var sessConn = &WebsocketSessionConnection{ conn: ws, } var session Session = endpoint.context.CreateSession(sessConn) fmt.Printf("New session: %s\n", session.ID()) for { msgLength, err := ws.Read(buf) if err != nil { if err != io.EOF { fmt.Printf("WS error: %#v\n", err) } fmt.Printf("Session closed: %s\n", session.ID()) break } if msgLength == 0 { continue } var msgBuf = make([]byte, msgLength) copy(msgBuf, buf) endpoint.Handler(endpoint, msgBuf, session, ws) } }
func wshandler(ws *websocket.Conn) { flag.Parse() var mqcon net.Conn var err error if *bs { conf := tls.Config{InsecureSkipVerify: *bsinsec} if *bcert != "" && *bkey != "" { Cert, err := tls.LoadX509KeyPair(*bcert, *bkey) if err != nil { fmt.Println("LoadX509KeyPair:", err) return } conf.Certificates = []tls.Certificate{Cert} } mqcon, err = tls.Dial("tcp", *bhost+":"+*bport, &conf) } else { mqcon, err = net.Dial("tcp", *bhost+":"+*bport) } if err != nil { fmt.Println("mqcon error:", err.Error()) ws.Close() return } ws.PayloadType = websocket.BinaryFrame bmqcon := bufio.NewReadWriter(bufio.NewReader(mqcon), bufio.NewWriter(mqcon)) bws := bufio.NewReadWriter(bufio.NewReader(ws), bufio.NewWriter(ws)) go func() { for { msg, err := mqtt.DecodeOneMessage(bmqcon, nil) // fmt.Println("brok->", msg) if err != nil { mqcon.Close() return } wbuffer := new(bytes.Buffer) msg.Encode(wbuffer) bws.Write(wbuffer.Bytes()) bws.Flush() wbuffer.Truncate(wbuffer.Len()) } }() for { msg, err := mqtt.DecodeOneMessage(bws, nil) // fmt.Println("webs->", msg) if err != nil { ws.Close() return } msg.Encode(bmqcon) bmqcon.Flush() } }
func Processor(ws *websocket.Conn) { defer ws.Close() var head Head const headSize = unsafe.Sizeof(head) start_time = getNowMillisecond() ws.PayloadType = 2 file, err := os.Open("record.dat.2") if err != nil { log.Print(err) return } defer file.Close() for { size := int64(headSize) buf := make([]byte, size) n, err := file.Read(buf) if err == io.EOF { log.Print("got EOF in Read head") return } if err != nil { log.Print(err) return } if n != int(size) { log.Print("invlid head size.") return } err = binary.Read(bytes.NewBuffer(buf), binary.LittleEndian, &head) if err != nil { log.Print(err) return } buf = make([]byte, head.BodyLength) n, err = file.Read(buf) if err == io.EOF { log.Print("got EOF in Read body") return } if err != nil { log.Print(err) return } if n != int(head.BodyLength) { log.Print("invlid body size.") return } // ignore packet which send from ws client if head.Type == 1 { continue } now := getNowMillisecond() toffset := now - start_time var delay uint32 if head.TimeDelta <= uint32(toffset) { delay = 1 } else { delay = (head.TimeDelta) - uint32(toffset) } sleep := time.Duration(int(delay)) * time.Millisecond time.Sleep(sleep) n, err = ws.Write(buf) if err == syscall.EPIPE { log.Print("Websocket Got Broken PIPE") return } else if err != nil { log.Print("Websocket Write Failed") log.Print(err) return } if n != int(head.BodyLength) { log.Print("Send body failed") return } } }
func handleWebsocketConn(ws *websocket.Conn) { ws.PayloadType = websocket.BinaryFrame s := gameserver.NewSession(dispatcher.GetNextSessionId(), gameserver.RawPacketSerializer{}, ws, dispatcher.GetReceiver()) lobby.AddSession(s) s.Run() }
// 处理WebSocket客户端的VNC重新播放 func Processor(ws *websocket.Conn) { var start_time int64 var mutex sync.Mutex log.Println("Playback Server: New WebSocket Client: ", ws.Request().RemoteAddr) // 发送定时器 var timer *time.Timer // 暂停的标志 var pause bool = false // 接收恢复信号的同步channel resume_chan := make(chan bool) // 暂停时间的总和 var elapsed int64 // 设置WebSocket内容的编码类型为Binary ws.PayloadType = 2 notify_chan := make(chan bool) go WaitSignal(ws, notify_chan, &timer, &pause, resume_chan, &elapsed, &mutex) var filename string ws_query := ws.Request().URL.Query() if value, ok := ws_query["filename"]; ok { filename = value[0] } else { log.Println("Playback Server: Emptry filename in Query") return } defer ws.Close() // 设置开始时间 start_time = getNowMillisecond() // 判断文件路径是否正确 pwd, _ := os.Getwd() fullpath := path.Join(pwd, "data", filename) fullpath = path.Clean(fullpath) fullpath_dir := path.Dir(fullpath) correct_dir := path.Join(pwd, "data") if fullpath_dir != correct_dir { log.Println("Playback Server: Bad File Path To Open: ", fullpath) return } // 打开VNC记录文件 file, err := os.OpenFile(fullpath, os.O_RDONLY, 0664) if err != nil { log.Println("Playback Server: Failed to open VNC Data file: ", err) return } defer file.Close() err = syscall.Flock(int(file.Fd()), syscall.LOCK_SH|syscall.LOCK_NB) if err != nil { log.Printf("Playback Server: Set %s Shared Lock Failed: %s\n", file.Name(), err) return } // 循环发送VNC记录文件,直到文件结束 for { select { // 从channel中读取信号,并退出函数 case quit := <-notify_chan: if quit == true { log.Println("Playback Server: Receive Close Signal, Quit Goroutine Now.") goto end } default: if !pause { // 获取Head结构体大小 var head Head const headSize = unsafe.Sizeof(head) size := int64(headSize) buf := make([]byte, size) n, err := file.Read(buf) if err == io.EOF { log.Print("Playback Server: got EOF in Read head") goto end } if err != nil { log.Print("Playback Server: Failed to Read Head", err) goto end } if n != int(size) { log.Print("Playback Server: invlid head size.") goto end } err = binary.Read(bytes.NewBuffer(buf), binary.LittleEndian, &head) if err != nil { log.Print("Playback Server: Failed to Parse Head: ", err) goto end } buf = make([]byte, head.BodyLength) n, err = file.Read(buf) if err == io.EOF { log.Print("Playback Server: got EOF in Read body") goto end } if err != nil { log.Print("Playback Server: Failed to Read Boby: ", err) goto end } if n != int(head.BodyLength) { log.Print("Playback Server: invlid body size.") goto end } // 忽略是WebSocket客户端发送的帧 if head.Type == 1 { continue } // 将文件中记录的暂停时间 // 加上elapsed作为补偿 head.TimeDelta += uint32(elapsed) now := getNowMillisecond() toffset := now - start_time var delay uint32 if (head.TimeDelta) < uint32(toffset) { delay = 1 } else { delay = (head.TimeDelta) - uint32(toffset) } sleep := time.Duration(int(delay)) * time.Millisecond mutex.Lock() timer = time.NewTimer(sleep) mutex.Unlock() <-timer.C n, err = ws.Write(buf) if err == syscall.EPIPE { log.Print("Playback Server: Websocket Got Broken PIPE") goto end } else if err != nil { log.Print("Playback Server: Websocket Write Failed") log.Print(err) goto end } if n != int(head.BodyLength) { log.Print("Playback Server: Send body failed") goto end } } else { // 如果已经暂停 // 则以阻塞的方式读取channel <-resume_chan } } } end: err = syscall.Flock(int(file.Fd()), syscall.LOCK_UN|syscall.LOCK_NB) if err != nil { log.Printf("Playback Server: UNLock %s Failed: %s\n", file.Name(), err) return } log.Println("Playback Server: Close WebSocket Connection: ", ws.Request().RemoteAddr) }