Beispiel #1
0
//---------------------------------------------------------- Hub processing
func HubAgent(incoming chan []byte, conn net.Conn) {
	config := cfg.Get()
	if config["profile"] == "true" {
		helper.SetMemProfileRate(1)
		defer func() {
			helper.GC()
			helper.DumpHeap()
			helper.PrintGCSummary()
		}()
	}

	hostid := atomic.AddInt32(&_host_genid, 1)
	// forward buffer
	forward := make(chan []byte, MAXCHAN)
	// output buffer
	output := make(chan []byte, MAXCHAN)

	protos.AddServer(hostid, forward)
	log.Printf("game server [id:%v] connected\n", hostid)

	go _write_routine(output, conn)

	defer func() {
		protos.RemoveServer(hostid)
		core.LogoutServer(hostid)
		close(forward)
		close(output)

		log.Printf("game server [id:%v] disconnected\n", hostid)
	}()

	for {
		select {
		case msg, ok := <-incoming: // from hub
			if !ok {
				return
			}

			reader := packet.Reader(msg)
			protos.HandleRequest(hostid, reader, output)
		case msg := <-forward: // send forward packet
			helper.SendChan(0, msg, output)
		}
	}

}
Beispiel #2
0
//---------------------------------------------------------- Event Server start
func EventStart() {
	config := cfg.Get()
	if config["profile"] == "true" {
		helper.SetMemProfileRate(1)
		defer func() {
			helper.GC()
			helper.DumpHeap()
			helper.PrintGCSummary()
		}()
	}

	// start logger
	if config["event_log"] != "" {
		cfg.StartLogger(config["event_log"])
	}

	log.Println("Starting Event Server")
	startup_work()
	go SignalProc()

	// Listen
	service := DEFAULT_SERVICE
	if config["event_service"] != "" {
		service = config["event_service"]
	}

	log.Println("Event Service:", service)
	tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
	checkError(err)

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

	log.Println("Event Server OK.")
	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			continue
		}
		helper.SetConnParam(conn)
		go handleClient(conn)
	}
}
Beispiel #3
0
func yyParse(yylex yyLexer) int {
	var yyn int
	var yylval yySymType
	var yyVAL yySymType
	yyS := make([]yySymType, yyMaxDepth)

	Nerrs := 0   /* number of errors */
	Errflag := 0 /* error recovery flag */
	yystate := 0
	yychar := -1
	yyp := -1
	goto yystack

ret0:
	return 0

ret1:
	return 1

yystack:
	/* put a state and value onto the stack */
	if yyDebug >= 4 {
		__yyfmt__.Printf("char %v in %v\n", yyTokname(yychar), yyStatname(yystate))
	}

	yyp++
	if yyp >= len(yyS) {
		nyys := make([]yySymType, len(yyS)*2)
		copy(nyys, yyS)
		yyS = nyys
	}
	yyS[yyp] = yyVAL
	yyS[yyp].yys = yystate

yynewstate:
	yyn = yyPact[yystate]
	if yyn <= yyFlag {
		goto yydefault /* simple state */
	}
	if yychar < 0 {
		yychar = yylex1(yylex, &yylval)
	}
	yyn += yychar
	if yyn < 0 || yyn >= yyLast {
		goto yydefault
	}
	yyn = yyAct[yyn]
	if yyChk[yyn] == yychar { /* valid shift */
		yychar = -1
		yyVAL = yylval
		yystate = yyn
		if Errflag > 0 {
			Errflag--
		}
		goto yystack
	}

yydefault:
	/* default state action */
	yyn = yyDef[yystate]
	if yyn == -2 {
		if yychar < 0 {
			yychar = yylex1(yylex, &yylval)
		}

		/* look through exception table */
		xi := 0
		for {
			if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate {
				break
			}
			xi += 2
		}
		for xi += 2; ; xi += 2 {
			yyn = yyExca[xi+0]
			if yyn < 0 || yyn == yychar {
				break
			}
		}
		yyn = yyExca[xi+1]
		if yyn < 0 {
			goto ret0
		}
	}
	if yyn == 0 {
		/* error ... attempt to resume parsing */
		switch Errflag {
		case 0: /* brand new error */
			yylex.Error("syntax error")
			Nerrs++
			if yyDebug >= 1 {
				__yyfmt__.Printf("%s", yyStatname(yystate))
				__yyfmt__.Printf("saw %s\n", yyTokname(yychar))
			}
			fallthrough

		case 1, 2: /* incompletely recovered error ... try again */
			Errflag = 3

			/* find a state where "error" is a legal shift action */
			for yyp >= 0 {
				yyn = yyPact[yyS[yyp].yys] + yyErrCode
				if yyn >= 0 && yyn < yyLast {
					yystate = yyAct[yyn] /* simulate a shift of "error" */
					if yyChk[yystate] == yyErrCode {
						goto yystack
					}
				}

				/* the current p has no shift on "error", pop stack */
				if yyDebug >= 2 {
					__yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys)
				}
				yyp--
			}
			/* there is no state on the stack with an error shift ... abort */
			goto ret1

		case 3: /* no shift yet; clobber input char */
			if yyDebug >= 2 {
				__yyfmt__.Printf("error recovery discards %s\n", yyTokname(yychar))
			}
			if yychar == yyEofCode {
				goto ret1
			}
			yychar = -1
			goto yynewstate /* try again in the same state */
		}
	}

	/* reduction by production yyn */
	if yyDebug >= 2 {
		__yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate))
	}

	yynt := yyn
	yypt := yyp
	_ = yypt // guard against "declared and not used"

	yyp -= yyR2[yyn]
	yyVAL = yyS[yyp+1]

	/* consult goto table to find next state */
	yyn = yyR1[yyn]
	yyg := yyPgo[yyn]
	yyj := yyg + yyS[yyp].yys + 1

	if yyj >= yyLast {
		yystate = yyAct[yyg]
	} else {
		yystate = yyAct[yyj]
		if yyChk[yystate] != -yyn {
			yystate = yyAct[yyg]
		}
	}
	// dummy call; replaced with literal code
	switch yynt {

	case 3:
		//line ./src/inspect/inspect.y:30
		{
			prompt(conn)
		}
	case 10:
		//line ./src/inspect/inspect.y:42
		{
			ListAll(conn)
			prompt(conn)
		}
	case 11:
		//line ./src/inspect/inspect.y:50
		{
			fmt.Fprintln(conn, "\t(p)rint user_id: inspect a user struct")
			fmt.Fprintln(conn, "\t(p)rint user_id.Field1.Field2...: dotted fields")
			fmt.Fprintln(conn, "\t(l)ist: list all online users")
			fmt.Fprintln(conn, "\tgc: force a garbage collection")
			prompt(conn)
		}
	case 12:
		//line ./src/inspect/inspect.y:61
		{
			conn.Close()
		}
	case 13:
		//line ./src/inspect/inspect.y:68
		{
			Inspect(int32(yyS[yypt-0].n), conn)
			prompt(conn)
		}
	case 14:
		//line ./src/inspect/inspect.y:74
		{
			InspectField(int32(yyS[yypt-1].n), yyS[yypt-0].nodes, conn)
			prompt(conn)
		}
	case 15:
		//line ./src/inspect/inspect.y:81
		{
			helper.GC()
			helper.FprintGCSummary(conn)
			prompt(conn)
		}
	}
	goto yystack /* stack new state and value */
}
Beispiel #4
0
//----------------------------------------------- Start Agent when a client is connected
func StartAgent(in chan []byte, conn net.Conn) {
	defer helper.PrintPanicStack()

	config := cfg.Get()
	if config["profile"] == "true" {
		helper.SetMemProfileRate(1)
		defer func() {
			helper.GC()
			helper.DumpHeap()
			helper.PrintGCSummary()
		}()
	}

	var sess Session
	sess.IP = net.ParseIP(conn.RemoteAddr().String())
	sess.MQ = make(chan IPCObject, DEFAULT_MQ_SIZE)
	sess.ConnectTime = time.Now()
	sess.LastPacketTime = time.Now().Unix()
	sess.KickOut = false

	// standard 1-sec timer
	std_timer := make(chan int32, 1)
	timer.Add(1, time.Now().Unix()+1, std_timer)

	// write buffer
	bufctrl := make(chan bool)
	buf := NewBuffer(&sess, conn, bufctrl)
	go buf.Start()

	// max # of operartions allowed before flushing
	flush_ops, err := strconv.Atoi(config["flush_ops"])
	if err != nil {
		log.Println("cannot parse flush_ops from config", err)
		flush_ops = DEFAULT_FLUSH_OPS
	}

	// cleanup work
	defer func() {
		close_work(&sess)
		close(bufctrl)
	}()

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

			if result := UserRequestProxy(&sess, msg); result != nil {
				err := buf.Send(result)
				if err != nil {
					return
				}
			}
			sess.LastPacketTime = time.Now().Unix()

		case msg, ok := <-sess.MQ: // async
			if !ok {
				return
			}

			if result := IPCRequestProxy(&sess, &msg); result != nil {
				err := buf.Send(result)
				if err != nil {
					return
				}
			}

		case <-std_timer:
			timer_work(&sess)
			if session_timeout(&sess) {
				return
			}
			timer.Add(1, time.Now().Unix()+1, std_timer)
		}

		// 持久化逻辑#1: 超过一定的操作数量,刷入数据库
		if sess.OpCount > flush_ops {
			_flush(&sess)
		}

		// 是否被逻辑踢出
		if sess.KickOut {
			return
		}
	}
}