func (c *wsClient) handlerControlMessage(bFrame []byte) error { msg := ctrl.WebSocketControlFrame{} if err := json.Unmarshal(bFrame, &msg); err != nil { log.Warn("Recve a Text-Frame not JSON format. err=%v, frame=%v", err.Error(), string(bFrame)) return err } log.Debug("TCP[%v] Get Frame T[%v], Content=%v, index=%v, ", c, msg.TypeStr(), msg.Content, msg.Index) switch msg.Type { case ctrl.Msg_Request_Finish: c.closeWriter() case ctrl.Msg_Client_Busy: c.writerForward.Write([]byte("current client was busy, pls try anthor.")) c.closeWriter() case ctrl.Msg_Sys_Err: c.writerForward.Write([]byte(msg.Content)) c.closeWriter() case ctrl.Msg_Get_Config: log.Info("Get the Client- side local network server config[%s]", msg.Content) pConfig.client_conf_forward_host = msg.Content default: log.Warn("no handler Msg T[%s]", msg.TypeStr()) } return nil }
func (this *WebSocketControlFrame) TypeStr() string { s, ok := msgString[this.Type] if !ok { log.Warn("not found msg type[%v]", this.Type) } return s }
func WebsocketHandler(w http.ResponseWriter, r *http.Request) { log.Info("WebsocketHandler:%s %s %s", r.RemoteAddr, r.Method, r.URL.Path) if !authOK(r) { log.Warn("auth fail....") noAuthResponse(w) return } var conn *websocket.Conn conn, err := websocket.Upgrade(w, r, http.Header{}) if err != nil { log.Error(err.Error()) return } conn.SetReadDeadline(time.Time{}) conn.SetWriteDeadline(time.Time{}) var client = newWebsocketClient(conn, r) if pConfig.client_conf_forward_host == "" { log.Info("pConfig.client_conf_forward_host is empty. tell Client Need the Config.") client.tellClientNeedConfig() } log.Info("Put[%s] into the global Connect pool.", client) client.waitForFrameLoop() websocketClose(r) log.Debug("WebsocketHandler:%s closed.", r.RemoteAddr) }
func (c *Client) newConnect2LoalNetwork() error { if pConfig.currThread < pConfig.MaxThread { go Connect2Serv(pConfig.orwardServ, pConfig) } // 与本地局域网服务器g_localForwardHostAndPort 建立socket连接 c.rw.Lock() defer c.rw.Unlock() if c.localConn != nil { log.Warn("[%s], thread is busy. can not create new connect.", c) c.tellServBusy() return fmt.Errorf("[%s] thread is busy. can not create new connect.", c) } conn, err := net.Dial("tcp", g_localForwardHostAndPort) if err != nil { log.Error("[%s] Connect to[%s] err=%s", c, g_localForwardHostAndPort, err.Error()) c.tellServError(err) return err } go c.readForward(conn) c.localConn = &conn c.forwardData = make(chan []byte, Default_Channel_Size*4) go c.writerForward(conn) log.Info("new connection was create [%s]", conn.RemoteAddr()) return nil }
func (client *wsClient) waitForFrameLoop() { for { frameType, bFrame, err := client.websocket.Read() log.Debug("TCP[%s] recv WebSocket Frame typ=[%v] size=[%d], crc32=[%d]", client, frameTypStr(frameType), len(bFrame), crc32.ChecksumIEEE(bFrame)) if err != nil { if err != io.ErrUnexpectedEOF { log.Error("TCP[%s] close Unexpected err=%v", client, err.Error()) } else { log.Debug("TCP[%s] close the socket. EOF.", client) } client.closeWriter() return } switch frameType { case websocket.TextMessage: client.handlerControlMessage(bFrame) case websocket.CloseMessage: log.Info("TCP[%s] close Frame revced. end wait Frame loop", client) client.closeWriter() return case websocket.BinaryMessage: log.Info("TCP[%s] resv-binary: %v", client, len(bFrame)) if client.writerForward == nil { log.Warn("client.writerForward is nil.") continue } _, err := client.writerForward.Write(bFrame) if err != nil { if err != io.EOF { log.Error(err.Error()) } client.tellClientRequestFinish() client.closeWriter() } case websocket.PingMessage, websocket.PongMessage: // IE-11 会无端端发一个pong上来 client.websocket.Pong(bFrame) default: log.Warn("TODO: revce frame-type=%v. can not handler. content=%v", frameTypStr(frameType), string(bFrame)) } } }
func (c *wsClient) closeWriter() { if c.writerForward == nil { log.Warn("whan to close an nil client.writerForward.") return } c.rw.Lock() defer c.rw.Unlock() c.writerForward.Close() c.working = false }
func (client *Client) waitForCommand() { for { frameType, bFrame, err := client.webSocket.Read() log.Debug("TCP[%s] recv WebSocket Frame typ=[%v] size=[%d], crc32=[%d]", client, frameTypStr(frameType), len(bFrame), crc32.ChecksumIEEE(bFrame)) if err != nil { if err != io.ErrUnexpectedEOF { log.Error("TCP[%s] close Unexpected err=%v", client, err.Error()) } else { log.Debug("TCP[%s] close the socket. EOF.", client) } client.closeLocalConnect() return } switch frameType { case websocket.CloseMessage: log.Info("TCP[%s] close Frame revced. end wait Frame loop", client) client.closeLocalConnect() return case websocket.TextMessage: err := client.handlerControlFrame(bFrame) if err != nil { log.Error("handlerControlFrame ret[%s]", err.Error()) } case websocket.BinaryMessage: log.Info("put Binary-Data to chan-len[%d]", len(client.forwardData)) select { case client.forwardData <- bFrame: log.Info("put frame to client.forwardData len[%d] end", len(client.forwardData)) default: log.Warn("[%s] is busy", client) client.tellServBusy() } case websocket.PingMessage, websocket.PongMessage: // IE-11 会无端端发一个pong上来 client.webSocket.Pong(bFrame) default: log.Warn("TODO: revce frame-type=%v. can not handler. content=%v", frameTypStr(frameType), string(bFrame)) } } }
func (this *Connect) pushToClient() { go func() { for s := range this.Chan { if _, err := this.Conn.Write(s); err != nil { log.Warn("Can't send msg. %v", err) } else { log.Info("Send Success") } } }() }
// 从客户端读取信息 func (this *Connect) PullFromClient() { for { defer func() { if err := recover(); err != nil { log.Critical("Panic occur. %v", err) this.Send(lineNum(), fmt.Sprintf("%v", err)) this.PullFromClient() } }() var content []byte err := websocket.Message.Receive(this.Conn, &content) if err != nil { log.Info("Websocket Error: %v", err) playerMap.Delete(this.Uid, this) return } beginTime := time.Now() log.Info(" Begin ") // parse proto message this.Request, err = ParseContent(content) if err != nil { log.Error("Parse client request error. %v", err) this.Send(lineNum(), err) continue } if this.Request.GetCmdId() != LOGIN { if !this.verify(this.Request.GetTokenStr()) { continue } } this.Function(this.Request.GetCmdId())() execTime := time.Now().Sub(beginTime) if execTime.Seconds() > 0.1 { // slow log log.Warn("Slow Exec , time is %v second", execTime.Seconds()) } else { log.Info("time is %v second", execTime.Seconds()) } } }
func newWebsocketClient(conn *websocket.Conn, r *http.Request) *wsClient { var client = &wsClient{ websocket: conn, working: false, rw: new(sync.RWMutex), req: r, finish: make(chan int, 1), } _OnlineClient.rw.Lock() defer _OnlineClient.rw.Unlock() if cli, find := _OnlineClient.onlines[r.RemoteAddr]; find { log.Warn("client[%s] is working[%s].", cli.req.RemoteAddr, cli.working) panic("some closed client did not remove from _OnlineClient ?") } _OnlineClient.onlines[r.RemoteAddr] = client return client }
func (c *Client) handlerControlFrame(bFrame []byte) (err error) { msg := ctrl.WebSocketControlFrame{} if err = json.Unmarshal(bFrame, &msg); err != nil { log.Error("Recve a Text-Frame not JSON format. err=%v, frame=%v", err.Error(), string(bFrame)) return err } log.Info("TCP[%v] Get Frame T[%v], Content=%v, index=%v, ", c, msg.TypeStr(), msg.Content, msg.Index) switch msg.Type { case ctrl.Msg_New_Connection: c.newConnect2LoalNetwork() case ctrl.Msg_Request_Finish: c.closeLocalConnect() case ctrl.Msg_Get_Config: err = c.telServConfig() case ctrl.Msg_Set_Config: pConfig.LocalHostServ = msg.Content err = c.telServConfig() default: log.Warn("no handler Msg T[%s]", msg.TypeStr()) } return err }
func httpConfirm(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { log.Critical("RPC Panic: %v", err) } }() orderId := r.FormValue("order_id") if orderId == "" { return } OrderData, err := models.Order.Order(orderId) if err != nil { return } conn := playerMap.Get(OrderData.Uid) var RoleData *models.RoleData if conn != nil && conn.Role != nil { RoleData = conn.Role } else { RoleData, err = models.Role.Role(OrderData.Uid) if err != nil { return } } // ----- 启动事务 ----- if OrderData.Status != 1 { log.Warn("Order status not is '1' ORDERID: %s", orderId) return } Transaction, err := models.DB().Begin() if err != nil { log.Warn("%v", err) return } OrderData.Status = 2 affected_rows, err := Transaction.Update(OrderData) if err != nil || affected_rows != 1 { Transaction.Rollback() log.Warn("%v", err) return } oldDiamond := RoleData.Diamond RoleData.Diamond += OrderData.Diamond RoleData.UnixTime = time.Now().Unix() _, err = Transaction.Update(RoleData) if err != nil { RoleData.Diamond = oldDiamond Transaction.Rollback() log.Warn("%v", err) return } // ----- 提交 ----- if Transaction.Commit() != nil { RoleData.Diamond = oldDiamond Transaction.Rollback() log.Warn("%v", err) return } models.InsertSubDiamondFinanceLog(OrderData.Uid, models.FINANCE_BUY_DIAMOND, oldDiamond, RoleData.Diamond, fmt.Sprintf("orderId: %s", orderId)) if conn != nil { *conn.Request.CmdId = 10121 *conn.Request.CmdIndex = 10121 conn.Send(StatusOK, &protodata.PaySuccessResponse{Role: roleProto(RoleData)}) } }