コード例 #1
0
ファイル: netservice.go プロジェクト: skOak/chestnut
func socketTlsListener(quit chan int, gameLogic func(*Client), portn int, readDeadline, writeDeadline time.Duration, config *tls.Config) {
	port := fmt.Sprintf(":%d", portn)
	ln, err := tls.Listen("tcp", port, config)
	if err != nil {
		log.Debugf("listen on port %d failed %s \n", port, err.Error())
		quit <- 1
		return
	}

	log.Debug("starting socket")
	for {
		conn, err := ln.Accept()
		if err != nil {
			log.Debug("accept connection failed")
			continue
		}

		client := new(Client)
		client.Conn = conn
		client.ReadDeadline = readDeadline
		client.WriteDeadline = writeDeadline
		client.Request = make(chan ClientRequest)
		client.Response = make([]chan ClientResponse, NetChannelCount)
		client.Connected = true
		//client.DisconnectEvents = make([]chan bool, 0)
		client.DisconnectHandlers = make([]*ClientDisconnectHandler, 0)

		for i := 0; i < NetChannelCount; i++ {
			client.Response[i] = make(chan ClientResponse)
		}

		go handleConnection(client)
		go gameLogic(client)
	}
}
コード例 #2
0
ファイル: base.go プロジェクト: skOak/chestnut
func (bs *BaseService) loadConfig(configPath string) error {
	file, err := os.Open(configPath)
	if err == nil {
		defer file.Close()
		decoder := json.NewDecoder(file)
		err = decoder.Decode(&bs.config)
	} else {
		err = errors.New(fmt.Sprintf("%s Configuration File Not Found", configPath))
	}

	if err != nil {
		return err
	}

	if bs.config.Server.ReadDeadline < 0 {
		bs.config.Server.ReadDeadline = 0
	} else if bs.config.Server.ReadDeadline == 0 {
		bs.config.Server.ReadDeadline = 3 * bus.HeartBeatRate
	}

	bs.config.Valid = true

	log.Debug("loadConfig : %+v\n", bs.config)

	return nil
}
コード例 #3
0
ファイル: db.go プロジェクト: skOak/chestnut
func (ds *DBService) initDBConn() (err error) {
	if ds.running {
		return errors.New("Can not init DB connection while a service is running")
	}

	if !ds.config.Valid {
		return errors.New("Config is not valid")
	}

	if !ds.config.DBConfig.DBEnable {
		return errors.New("DB is not enabled for this service")
	}

	connStr := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", ds.config.DBConfig.DBUser, ds.config.DBConfig.DBPassword, ds.config.DBConfig.DBAddress, ds.config.DBConfig.DBPort, ds.config.DBConfig.DBScheme)
	ds.db, err = sql.Open("mysql", connStr)
	if err != nil {
		panic(err.Error())
	}

	err = ds.db.Ping()
	if err != nil {
		panic(err.Error())
	} else {
		log.Debug("database connected")
	}

	ds.db.SetMaxIdleConns(ds.config.DBConfig.DBMaxConn / 2)
	ds.db.SetMaxOpenConns(ds.config.DBConfig.DBMaxConn)

	return
}
コード例 #4
0
ファイル: login.go プロジェクト: skOak/chestnut
// send all requests to connector
func (ls *LoginService) requestDispatch(client *net.Client, reqType, request string) {
	log.Debugf("requestDispatch:reqType(%v),request(%v) for playerId(%d)\n", reqType, request, client.Id)

	if ls.busStub == nil {
		panic("BusStub of LoginService doesn't exist!")
	}

	var args CommonRequest
	args.Type = reqType
	args.Service = "Service"
	args.Handler = reqType
	args.PlayerId = client.Id
	args.Content = request
	var reply CommonReply
	rpcCallHandle, err := ls.busStub.GoByMethod("GameService."+reqType, args, &reply)
	//rpcCallHandle, err := busStub.GoByType("GameCommon", "GameService."+reqType, args, &reply)
	if err != nil {
		panic(err.Error())
	}
	if rpcCallHandle == nil {
		panic("rpcCallHandle nil")
	}

	// Todo:reconstruct to an independent goroutine
	go func(reply *CommonReply) {
		defer func() {
			if x := recover(); x != nil {
				var request net.ClientRequest
				request.Type = "Exception"
				request.Content = fmt.Sprint(x)

				client.Request <- request
				log.Debug(x, string(debug.Stack()))
			}
		}()

		for {
			select {
			case rpcReplyError := <-rpcCallHandle:
				if rpcReplyError != nil {
					panic(rpcReplyError.Error())
				}
				client.SendResponse(reply)
				break
			case <-time.After(time.Second * RPCCallTimeOut):
				// Todo:mark rpc call abandoned
			}
		}
	}(&reply)
}
コード例 #5
0
ファイル: netservice.go プロジェクト: skOak/chestnut
func handleConnection(client *Client) {
	defer func() {
		if x := recover(); x != nil {
			log.Debugf("connection from %s to %s lost\n", client.Conn.RemoteAddr().String(), client.Conn.LocalAddr().String())
			log.Debug(x)
			client.Disconnect()

			go func() {
				for {
					timeout := false
					select {
					case request := <-client.Request:
						log.Debugf("remove tail request for account %d with request %s", client.Id, request.Content)
					case <-time.After(time.Second * 60):
						timeout = true
					}
					if timeout {
						break
					}
				}
			}()

			var exception struct {
				Type string
			}
			exception.Type = "Exception"
			var response ClientResponse
			bodybytes, _ := json.Marshal(exception)
			response.Content = string(bodybytes)
			client.Response[NetChannelPrimary] <- response
		}
		log.Debugf("Quit handleConnection : player %d\n", client.Id)
	}()

	log.Debugf("start handle connection from %s to %s \n", client.Conn.RemoteAddr().String(), client.Conn.LocalAddr().String())

	go handleResponse(client)
	defer client.Conn.Close()

	for {
		request := <-client.Request
		if request.Type == "Exception" {
			panic(request.Content)
		}
		client.Send(request.Channel, request.Content, request.Data)
	}
}
コード例 #6
0
ファイル: gateservice.go プロジェクト: skOak/chestnut
func main() {
	defer func() {
		if x := recover(); x != nil {
			log.Debug(x, string(debug.Stack()))
		}
	}()

	rand.Seed(time.Now().UnixNano())

	err := log.Init("", log.LogAll)
	if err != nil {
		panic(err.Error())
	}
	defer log.Close()

	Quit = make(chan int)

	service, err := services.CreateService(services.ServiceTypeGate)
	if err != nil {
		panic(err.Error())
	}
	if service == nil {
		panic("services.CreateService returned nil service without error")
	}

	err = service.Init(serverConfigPath)
	if err != nil {
		panic(err.Error())
	}

	// register customed handlers
	nHandler := new(notify.NotifyService)
	err = service.RegisterHandler("NotifyService", nHandler)
	if err != nil {
		panic(err.Error())
	}

	// start gate service
	err = service.Start()
	if err != nil {
		panic(err.Error())
	}

	<-Quit
}
コード例 #7
0
ファイル: loginservice.go プロジェクト: skOak/chestnut
func main() {
	defer func() {
		if x := recover(); x != nil {
			log.Debug(x, string(debug.Stack()))
		}
	}()

	rand.Seed(time.Now().UnixNano())

	err := log.Init("", log.LogAll)
	if err != nil {
		panic(err.Error())
	}
	defer log.Close()

	Quit = make(chan int)

	service, err := services.CreateService(services.ServiceTypeLogin)
	if err != nil {
		panic(err.Error())
	}
	if service == nil {
		panic("services.CreateService returned nil service without error")
	}

	err = service.Init(serverConfigPath)
	if err != nil {
		panic(err.Error())
	}

	// start login service
	err = service.Start()
	if err != nil {
		panic(err.Error())
	}

	<-Quit
}
コード例 #8
0
ファイル: login.go プロジェクト: skOak/chestnut
func (ls *LoginService) handleGateLogic(client *net.Client) {
	defer func() {
		if x := recover(); x != nil {
			var request net.ClientRequest
			request.Type = "Exception"
			request.Content = fmt.Sprint(x)

			client.Request <- request
			log.Debug(x, string(debug.Stack()))
		}
	}()

	if ls.busStub == nil {
		panic("BusStub of LoginService doesn't exist!")
	}

	if ls.config.Server.NeedAuth {
		var body net.BODYHEAD
		response := <-client.Response[net.NetChannelPrimary]
		err := json.Unmarshal([]byte(response.Content), &body)
		if err != nil {
			panic(err.Error())
		}
		// must auth synchronize at first
		if body.Type != "Login" {
			panic("the first request must be Login")
			return
		}

		var args CommonRequest
		args.Type = body.Type
		args.PlayerId = 0
		args.Service = "Service"
		args.Handler = "Login"
		args.Content = response.Content
		var reply CommonReply
		err = ls.busStub.CallByType("GameAuth", "GameService.Login", args, &reply)
		if err != nil {
			panic(err.Error())
			return
		}

		client.SendResponse(reply.Content)
		if reply.Result != ResultSuccess {
			return
		}

		client.Id = reply.PlayerId
		net.Clients[client.Id] = client
		log.Debugf("handleGateLogic:net.Clients(%+v)\n", net.Clients)
	}

	for {
		select {
		case response := <-client.Response[net.NetChannelPrimary]:
			var body net.BODYHEAD
			json.Unmarshal([]byte(response.Content), &body)
			switch body.Type {
			case "Beat":
				net.HandleBeat(client, response.Content)
			case "Exception":
				log.Debugf("Quit handleGateLogic : player %d\n", client.Id)
			default:
				ls.requestDispatch(client, body.Type, response.Content)
			}
		case <-time.After(time.Second * net.HeartBeatRate * 12):
			client.CloseConnection()
			log.Debugf("connection from %s timeout, closing logic thread", client.Conn.RemoteAddr())
			return
		}
	}
}