當前位置: 首頁>>代碼示例>>Golang>>正文


Golang utils.PrintPanicStack函數代碼示例

本文整理匯總了Golang中utils.PrintPanicStack函數的典型用法代碼示例。如果您正苦於以下問題:Golang PrintPanicStack函數的具體用法?Golang PrintPanicStack怎麽用?Golang PrintPanicStack使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。


在下文中一共展示了PrintPanicStack函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。

示例1: agent

// PIPELINE #2: agent
// all the packets from handleClient() will be handled
func agent(sess *Session, in chan []byte, out *Buffer) {
	defer wg.Done() // will decrease waitgroup by one, useful for manual server shutdown
	defer utils.PrintPanicStack()

	// init session
	sess.MQ = make(chan pb.Game_Frame, DEFAULT_MQ_SIZE)
	sess.ConnectTime = time.Now()
	sess.LastPacketTime = time.Now()
	// minute timer
	min_timer := time.After(time.Minute)

	// cleanup work
	defer func() {
		close(sess.Die)
		if sess.Stream != nil {
			sess.Stream.CloseSend()
		}
	}()

	// >> the main message loop <<
	// handles 4 types of message:
	//  1. from client
	//  2. from game service
	//  3. timer
	//  4. server shutdown signal
	for {
		select {
		case msg, ok := <-in: // packet from network
			if !ok {
				return
			}

			sess.PacketCount++
			sess.PacketTime = time.Now()

			if result := proxy_user_request(sess, msg); result != nil {
				out.send(sess, result)
			}
			sess.LastPacketTime = sess.PacketTime
		case frame := <-sess.MQ: // packets from game
			switch frame.Type {
			case pb.Game_Message:
				out.send(sess, frame.Message)
			case pb.Game_Kick:
				sess.Flag |= SESS_KICKED_OUT
			}
		case <-min_timer: // minutes timer
			timer_work(sess, out)
			min_timer = time.After(time.Minute)
		case <-die: // server is shuting down...
			sess.Flag |= SESS_KICKED_OUT
		}

		// see if the player should be kicked out.
		if sess.Flag&SESS_KICKED_OUT != 0 {
			return
		}
	}
}
開發者ID:tarmylan,項目名稱:agent,代碼行數:61,代碼來源:agent.go

示例2: agent

// agent of user
func agent(sess *Session, in chan []byte, out *Buffer, sess_die chan bool) {
	defer wg.Done()
	defer utils.PrintPanicStack()

	// init session
	sess.MQ = make(chan spp.Game_Frame, DEFAULT_MQ_SIZE)
	sess.ConnectTime = time.Now()
	sess.LastPacketTime = time.Now()
	// minute timer
	min_timer := time.After(time.Minute)

	// cleanup work
	defer func() {
		close(sess_die)
		if sess.Stream != nil {
			sess.Stream.CloseSend()
		}
	}()

	// >> the main message loop <<
	for {
		select {
		case msg, ok := <-in: // packet from network
			if !ok {
				return
			}

			sess.PacketCount++
			sess.PacketTime = time.Now()

			if result := proxy_user_request(sess, msg); result != nil {
				out.send(sess, result)
			}
			sess.LastPacketTime = sess.PacketTime
		case frame := <-sess.MQ:
			switch frame.Type {
			case spp.Game_Message:
				out.send(sess, frame.Message)
			case spp.Game_Kick:
				sess.Flag |= SESS_KICKED_OUT
			}
		case <-min_timer: // minutes timer
			timer_work(sess, out)
			min_timer = time.After(time.Minute)
		case <-die: // server is shuting down...
			sess.Flag |= SESS_KICKED_OUT
		}

		// see if the player should be kicked out.
		if sess.Flag&SESS_KICKED_OUT != 0 {
			return
		}
	}
}
開發者ID:anders007,項目名稱:agent,代碼行數:55,代碼來源:agent.go

示例3: start

// packet sending goroutine
func (buf *Buffer) start() {
	defer utils.PrintPanicStack()
	for {
		select {
		case data := <-buf.pending:
			buf.raw_send(data)
		case <-buf.ctrl: // receive session end signal
			close(buf.pending)
			// close the connection
			buf.conn.Close()
			return
		}
	}
}
開發者ID:tarmylan,項目名稱:agent,代碼行數:15,代碼來源:buffer.go

示例4: main

func main() {
	// to catch all uncaught panic
	defer utils.PrintPanicStack()

	// open profiling
	go func() {
		log.Info(http.ListenAndServe("0.0.0.0:6060", nil))
	}()

	// set log prefix
	log.SetPrefix(SERVICE)

	// resolve address & start listening
	tcpAddr, err := net.ResolveTCPAddr("tcp4", _port)
	checkError(err)

	listener, err := net.ListenTCP("tcp", tcpAddr)
	checkError(err)

	log.Info("listening on:", listener.Addr())

	// startup
	startup()

LOOP:
	// loop accepting
	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			log.Warning("accept failed:", err)
			continue
		}
		go handleClient(conn) // start a goroutine for every incoming connection for reading

		// check server close signal
		select {
		case <-die:
			listener.Close()
			break LOOP
		default:
		}
	}

	// server closed, wait forever
	// other options:
	// select{} 	-- may cause deadlock detected error, not tested yet
	for {
		<-time.After(time.Second)
	}
}
開發者ID:tarmylan,項目名稱:agent,代碼行數:50,代碼來源:main.go

示例5: main

func main() {
	defer utils.PrintPanicStack()
	go func() {
		log.Info(http.ListenAndServe("0.0.0.0:6060", nil))
	}()

	log.SetPrefix(SERVICE)

	// resolve
	tcpAddr, err := net.ResolveTCPAddr("tcp4", _port)
	checkError(err)

	listener, err := net.ListenTCP("tcp", tcpAddr)
	checkError(err)

	log.Info("listening on:", listener.Addr())

	// init services
	sp.Init()

	// startup
	startup()

	// loop accepting
LOOP:
	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			log.Warning("accept failed:", err)
			continue
		}
		go handleClient(conn)

		// check server close signal
		select {
		case <-die:
			listener.Close()
			break LOOP
		default:
		}
	}

	// server closed, wait forever
	for {
		<-time.After(time.Second)
	}
}
開發者ID:CowLeo,項目名稱:agent,代碼行數:47,代碼來源:main.go

示例6: sig_handler

// handle unix signals
func sig_handler() {
	defer utils.PrintPanicStack()
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGTERM)

	for {
		msg := <-ch
		switch msg {
		case syscall.SIGTERM: // 關閉agent
			close(die)
			log.Info("sigterm received")
			log.Info("waiting for agents close, please wait...")
			wg.Wait()
			log.Info("agent shutdown.")
			os.Exit(0)
		}
	}
}
開發者ID:gameogre,項目名稱:agent,代碼行數:19,代碼來源:signal.go

示例7: start

// packet sending goroutine
// 數據包發送協程
func (buf *Buffer) start() {
	defer utils.PrintPanicStack()
	for {
		select {
		//監聽數據包管道
		case data := <-buf.pending:
			buf.raw_send(data)
		//監聽關閉管道
		//?Important
		//ctrl 指向的是 sess_die, 在main.go裏麵,已經有select監聽了? 此處會不會造成問題
		case <-buf.ctrl: //receive session end signal
			//關閉接收管道
			close(buf.pending)
			//關閉conn連接
			buf.conn.Close()
			return
		}
	}
}
開發者ID:pengswift,項目名稱:agent,代碼行數:21,代碼來源:buffer.go

示例8: main

//遊戲入口
func main() {
	defer utils.PrintPanicStack()
	go func() {
		log.Info(http.ListenAndServe("0.0.0.0:6060", nil))
	}()

	log.SetPrefix(SERVICE)

	tcpAddr, err := net.ResolveTCPAddr("tcp4", _port)
	checkError(err)

	listener, err := net.ListenTCP("tcp", tcpAddr)
	checkError(err)

	log.Info("listening on:", listener.Addr())

	// loop accepting
	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			log.Warning("accept failed:", err)
			continue
		}
		go handleClient(conn)

		// check server close signal
		select {
		case <-die:
			listener.Close()
			goto FINAL
		default:
		}
	}
FINAL:
	// server closed, wait forever
	// 此處為什麽要等1秒
	// 此處等待1秒鍾,隻是為了wg.Wait() 可以執行到,從而阻塞主線程
	for {
		<-time.After(time.Second)
	}
}
開發者ID:pengswift,項目名稱:agent,代碼行數:42,代碼來源:main.go

示例9: proxy_user_request

// client protocol handle proxy
func proxy_user_request(sess *Session, p []byte) []byte {
	start := time.Now()
	defer utils.PrintPanicStack()
	//解密
	if sess.Flag&SESS_ENCRYPT != 0 {
		//使用2組密鑰匙, 增加破解難度
		sess.Decoder.XORKeyStream(p, p)
	}

	//封裝成reader
	reader := packet.Reader(p)

	// 讀客戶端數據包序列號(1,2,3...)
	// 可避免重放攻擊-REPLAY-ATTACK
	//數據包的前4個字節存放的是客戶端的發包數量
	//客戶端每次發包要包含第幾次發包信息
	seq_id, err := reader.ReadU32()
	if err != nil {
		log.Error("read client timestamp failed:", err)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 數據包個數驗證
	if seq_id != sess.PacketCount {
		//數據包真實長度是,總長度-4個字節的包個數長度-2個字節的協議號長度
		log.Errorf("illegal packet sequeue id:%v should be:%v size:%v", seq_id, sess.PacketCount, len(p)-6)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 讀協議號
	b, err := reader.ReadS16()
	if err != nil {
		log.Error("read protocol number failed.")
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	//根據協議號段 做服務劃分
	var ret []byte
	if b > MAX_PROTO_NUM {
		//去除4字節發包個數,將其餘的向前傳遞
		if err := forward(sess, p[4:]); err != nil {
			log.Errorf("service id:%v execute failed, error:%v", b, err)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	} else {
		if h := client_handler.Handlers[b]; h != nil {
			ret = h(sess, reader)
		} else {
			log.Errorf("service id:%v not bind", b)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	}

	// 統計處理時間
	elasped := time.Now().Sub(start)
	if b != 0 { //排除心跳包日誌
		log.Trace("[REQ]", client_handler.RCode[b])
		_statter.Timing(1.0, fmt.Sprintf("%v%v", STATSD_PREFIX, client_handler.RCode[b]), elasped)
	}
	return ret
}
開發者ID:pengswift,項目名稱:agent,代碼行數:67,代碼來源:proxy.go

示例10: handleClient

// start a goroutine when a new connection is accepted
func handleClient(conn *net.TCPConn) {
	defer utils.PrintPanicStack()
	// set per-connection socket buffer
	conn.SetReadBuffer(SO_RCVBUF)

	// set initial socket buffer
	conn.SetWriteBuffer(SO_SNDBUF)

	// initial network control struct
	header := make([]byte, 2)
	in := make(chan []byte)
	defer func() {
		close(in) // session will close
	}()

	// create a new session object for the connection
	var sess Session
	host, port, err := net.SplitHostPort(conn.RemoteAddr().String())
	if err != nil {
		log.Error("cannot get remote address:", err)
		return
	}
	sess.IP = net.ParseIP(host)
	log.Infof("new connection from:%v port:%v", host, port)

	// session die signal
	sess.Die = make(chan struct{})

	// create a write buffer
	out := new_buffer(conn, sess.Die)
	go out.start()

	// start one agent for handling packet
	wg.Add(1)
	go agent(&sess, in, out)

	// network loop
	for {
		// solve dead link problem
		conn.SetReadDeadline(time.Now().Add(TCP_READ_DEADLINE * time.Second))
		n, err := io.ReadFull(conn, header)
		if err != nil {
			log.Warningf("read header failed, ip:%v reason:%v size:%v", sess.IP, err, n)
			return
		}
		size := binary.BigEndian.Uint16(header)

		// alloc a byte slice for reading
		payload := make([]byte, size)
		// read msg
		n, err = io.ReadFull(conn, payload)
		if err != nil {
			log.Warningf("read payload failed, ip:%v reason:%v size:%v", sess.IP, err, n)
			return
		}

		select {
		case in <- payload: // payload queued
		case <-sess.Die:
			log.Warningf("connection closed by logic, flag:%v ip:%v", sess.Flag, sess.IP)
			return
		}
	}
}
開發者ID:CowLeo,項目名稱:agent,代碼行數:65,代碼來源:main.go

示例11: proxy_user_request

// client protocol handle proxy
func proxy_user_request(sess *Session, p []byte) []byte {
	start := time.Now()
	defer utils.PrintPanicStack(sess, p)
	// 解密
	if sess.Flag&SESS_ENCRYPT != 0 {
		sess.Decoder.Codec(p)
	}

	// 封裝為reader
	reader := packet.Reader(p)

	// 讀客戶端數據包序列號(1,2,3...)
	// 可避免重放攻擊-REPLAY-ATTACK
	seq_id, err := reader.ReadU32()
	if err != nil {
		log.Error("read client timestamp failed:", err)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 讀協議號
	b, err := reader.ReadS16()
	if err != nil {
		log.Error("read protocol number failed.")
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 數據包序列號驗證
	if seq_id != sess.PacketCount {
		log.Errorf("illegal packet sequence id:%v should be:%v proto:%v size:%v", seq_id, sess.PacketCount, b, len(p)-6)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	var ret []byte
	if b > MAX_PROTO_NUM { // game協議
		// 透傳
		ret, err = forward(sess, p)
		if err != nil {
			log.Errorf("service id:%v execute failed", b)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	} else { // agent保留協議段 [0, MAX_PROTO_NUM]
		// handle有效性檢查
		h := client_handler.Handlers[b]
		if h == nil {
			log.Errorf("service id:%v not bind", b)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
		// 執行
		ret = h(sess, reader)
	}

	// 統計處理時間
	elasped := time.Now().Sub(start)
	if b != 0 { // 排除心跳包日誌
		log.Trace("[REQ]", b)
		_statter.Timing(1.0, fmt.Sprintf("%v%v", STATSD_PREFIX, b), elasped)
	}
	return ret
}
開發者ID:gameogre,項目名稱:agent,代碼行數:65,代碼來源:proxy.go

示例12: handleClient

// start a goroutine when a new connection is accepted
func handleClient(conn *net.TCPConn) {
	defer utils.PrintPanicStack()
	// set per-connection socket buffer
	//設置conn連接接受緩存的大小, 當超過緩存時, 會進入阻塞狀態,等待被讀取
	conn.SetReadBuffer(SO_RCVBUF)

	// set initial socket buffer
	//設置conn連接發送緩存的大小, 當超過緩存時, 會進入阻塞狀態,等待被發送成功
	conn.SetWriteBuffer(SO_SNDBUF)

	// initial network control struct
	// 初始化2個字節數組, 用於存儲header長度, 既後麵要讀取的文件長度
	header := make([]byte, 2)
	// 輸入流通道, 解析後的數據將放入,等待被處理
	in := make(chan []byte)

	//設置延遲函數,當玩家斷開連接時, 函數退出之前,關閉輸入流
	defer func() {
		close(in) // session will close
	}()

	// create a new session object for the connection
	//創建session對象, 用於封裝客戶端和服務器的信息交換
	var sess Session
	host, port, err := net.SplitHostPort(conn.RemoteAddr().String())
	if err != nil {
		log.Error("cannot get remote address:", err)
		return
	}
	//存儲用戶ip
	sess.IP = net.ParseIP(host)
	//打印用戶的ip和端口, 用戶可能會雙開?
	log.Infof("new connection from:%v port:%v", host, port)

	// session die signal
	sess_die := make(chan bool)

	//SESSION_DIE 監控有問題.................

	// create a write buffer
	// 創建寫入buffer對象
	out := new_buffer(conn, sess_die)
	go out.start()

	// start one agent for handling packet
	//記錄goroutine個數,讓係統接收到關閉命令後,會阻塞主線程,至少所有agent線程退出,已保證數據落地
	wg.Add(1)
	go agent(&sess, in, out, sess_die)

	//network loop
	for {
		// solve dead line problem
		// 設置讀超時時間, 如果在任意一次執行Read syscall 返回的時候,超過這個時間點, 則算超時
		conn.SetReadDeadline(time.Now().Add(TCP_READ_DEADLINE * time.Second))
		//先讀取2個字節頭文件長度
		n, err := io.ReadFull(conn, header)
		if err != nil {
			log.Warningf("read header failed, ip:%v reason:%v size:%v", sess.IP, err, n)
			return
		}
		//將2個字節數組轉成int16類型, 不丟失精度
		size := binary.BigEndian.Uint16(header)

		// alloc a byte slice for reading
		// 創建一個指定長度的切片,用於存放具體內容
		payload := make([]byte, size)
		//read msg
		n, err = io.ReadFull(conn, payload)
		if err != nil {
			log.Warningf("read payload failed, ip:%v reason:%v size:%v", sess.IP, err, n)
			return
		}

		select {
		//接收的數據,轉入in通道
		case in <- payload: //payload queued
			//監聽sess_die 通道
		case <-sess_die:
			log.Warning("connection closed by logic, flag:%v ip:%v", sess.Flag, sess.IP)
			return
		}
	}

	// 好像沒有處理連接超時, 如果玩家連上遊戲後,一直未操作,再次鏈接時,會是新的連接?難道客戶端在許久沒有操作的情況下,先發一次ping, 如果有響應,繼續操作,如果沒響應,則執行重連?

	// 如果玩家已經退出了遊戲,但是通過非正常途徑退出的,這時,服務器還保留著該session, 當玩家再次登陸時, 原先的連接何時刪除

}
開發者ID:pengswift,項目名稱:agent,代碼行數:89,代碼來源:main.go

示例13: proxy_user_request

// client protocol handle proxy
func proxy_user_request(sess *Session, p []byte) []byte {
	start := time.Now()
	defer utils.PrintPanicStack(sess, p)
	// 解密
	if sess.Flag&SESS_ENCRYPT != 0 {
		sess.Decoder.XORKeyStream(p, p)
	}
	// 封裝為reader
	reader := packet.Reader(p)

	// 讀客戶端數據包序列號(1,2,3...)
	// 客戶端發送的數據包必須包含一個自增的序號,必須嚴格遞增
	// 加密後,可避免重放攻擊-REPLAY-ATTACK
	seq_id, err := reader.ReadU32()
	if err != nil {
		log.Error("read client timestamp failed:", err)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 數據包序列號驗證
	if seq_id != sess.PacketCount {
		log.Errorf("illegal packet sequence id:%v should be:%v size:%v", seq_id, sess.PacketCount, len(p)-6)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 讀協議號
	b, err := reader.ReadS16()
	if err != nil {
		log.Error("read protocol number failed.")
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 根據協議號斷做服務劃分
	// 協議號的劃分采用分割協議區間, 用戶可以自定義多個區間,用於轉發到不同的後端服務
	var ret []byte
	if b > MAX_PROTO_NUM {
		if err := forward(sess, p[4:]); err != nil {
			log.Errorf("service id:%v execute failed, error:%v", b, err)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	} else {
		if h := client_handler.Handlers[b]; h != nil {
			ret = h(sess, reader)
		} else {
			log.Errorf("service id:%v not bind", b)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	}

	// 監控協議處理時間
	// 監控數值會發送到statsd,格式為:
	// API.XXX_REQ = 10ms
	elasped := time.Now().Sub(start)
	if b != 0 { // 排除心跳包日誌
		log.Trace("[REQ]", client_handler.RCode[b])
		_statter.Timing(1.0, fmt.Sprintf("%v%v", STATSD_PREFIX, client_handler.RCode[b]), elasped)
	}
	return ret
}
開發者ID:tarmylan,項目名稱:agent,代碼行數:65,代碼來源:proxy.go

示例14: handleClient

// PIPELINE #1: handleClient
// the goroutine is used for reading incoming PACKETS
// each packet is defined as :
// | 2B size |     DATA       |
//
func handleClient(conn *net.TCPConn) {
	defer utils.PrintPanicStack()
	// set socket read buffer
	conn.SetReadBuffer(SO_RCVBUF)
	// set socket write buffer
	conn.SetWriteBuffer(SO_SNDBUF)

	// for reading the 2-Byte header
	header := make([]byte, 2)
	// the input channel for agent()
	in := make(chan []byte)
	defer func() {
		close(in) // session will close
	}()

	// create a new session object for the connection
	// and record it's IP address
	var sess Session
	host, port, err := net.SplitHostPort(conn.RemoteAddr().String())
	if err != nil {
		log.Error("cannot get remote address:", err)
		return
	}
	sess.IP = net.ParseIP(host)
	log.Infof("new connection from:%v port:%v", host, port)

	// session die signal, will be triggered by agent()
	sess.Die = make(chan struct{})

	// create a write buffer
	out := new_buffer(conn, sess.Die)
	go out.start()

	// start agent for PACKET processing
	wg.Add(1)
	go agent(&sess, in, out)

	// read loop
	for {
		// solve dead link problem:
		// physical disconnection without any communcation between client and server
		// will cause the read to block FOREVER, so a timeout is a rescue.
		conn.SetReadDeadline(time.Now().Add(TCP_READ_DEADLINE * time.Second))

		// read 2B header
		n, err := io.ReadFull(conn, header)
		if err != nil {
			log.Warningf("read header failed, ip:%v reason:%v size:%v", sess.IP, err, n)
			return
		}
		size := binary.BigEndian.Uint16(header)

		// alloc a byte slice of the size defined in the header for reading data
		payload := make([]byte, size)
		n, err = io.ReadFull(conn, payload)
		if err != nil {
			log.Warningf("read payload failed, ip:%v reason:%v size:%v", sess.IP, err, n)
			return
		}

		// deliver the data to the input queue of agent()
		select {
		case in <- payload: // payload queued
		case <-sess.Die:
			log.Warningf("connection closed by logic, flag:%v ip:%v", sess.Flag, sess.IP)
			return
		}
	}
}
開發者ID:tarmylan,項目名稱:agent,代碼行數:74,代碼來源:main.go

示例15: agent

func agent(sess *Session, in chan []byte, out *Buffer, sess_die chan bool) {
	defer wg.Done()
	defer utils.PrintPanicStack()

	// init session
	//存儲玩家異步消息, 讓消息超過時, 會阻塞,等待等讀取,
	//那麽如果一直是滿的時,玩家好久沒上線
	//別的玩家發過來的消息會一直發送不過去, 這時會長期阻塞,怎麽解決, 發送方設置超時,當許久沒發送成功後,彈出對方信箱已滿?
	//  ...... 這裏是異步消息,還是離線消息?
	sess.MQ = make(chan []byte, DEFAULT_MQ_SIZE)
	sess.ConnectTime = time.Now()
	sess.LastPacketTime = time.Now()

	// minute timer
	min_timer := time.After(time.Minute)

	// cleanup work
	defer func() {
		close(sess_die)
		//  當session關閉時,連接遊戲後段的流需要關閉
		if sess.Stream != nil {
			sess.Stream.CloseSend()
		}
	}()

	// >> the main message loop <<
	for {
		select {
		case msg, ok := <-in: // packet from network
			if !ok {
				return
			}

			//數據包個數++
			sess.PacketCount++
			//更新接收數據包的時間
			sess.PacketTime = time.Now()

			//處理用戶請求
			if result := proxy_user_request(sess, msg); result != nil {
				//將結果發送出去
				out.send(sess, result)
			}
			//當處理完之後,將數據包時間設置成上個數據包時間
			sess.LastPacketTime = sess.PacketTime
			//如果異步通道有消息? (內部發送過來的消息)
		case frame := <-sess.MQ:
			switch frame.Type {
			case spp.Game_Message:
				out.send(sess, frame.Message)
				//如果是關閉命令, 則設置關閉狀態, (用於後台管理)
			case spp.Game_Kick:
				sess.Flag |= SESS_KICKED_OUT
			}
		case <-min_timer: //minutes timer
			//定時器工作, 用於檢測用戶行為,防治玩家作弊
			timer_work(sess, out)
			min_timer = time.After(time.Minute)
		case <-die: // server is shuting down...
			sess.Flag |= SESS_KICKED_OUT
		}

		// see if the player should be kicked out.
		if sess.Flag&SESS_KICKED_OUT != 0 {
			return
		}
	}
}
開發者ID:pengswift,項目名稱:agent,代碼行數:68,代碼來源:agent.go


注:本文中的utils.PrintPanicStack函數示例由純淨天空整理自Github/MSDocs等開源代碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。