Beispiel #1
0
func (h *Service) GetSkillTemplates(req common.CommonRequest, reply *common.CommonReply) (err error) {
	log.Debugf("GetSkillTemplates:req(%+v)\n", req)

	var args common.CommonRequest
	args.PlayerId = req.PlayerId
	args.Content = nil
	err = h.connector.CallByMethod("Skill.GetSkillTemplates", args, reply)
	reply.Type = req.Type

	// test Notify
	defer func(args common.CommonRequest, reply *common.CommonReply) {
		var notify struct {
			Type    string
			Message string
		}
		notify.Type = "NotifyTest"
		notify.Message = "Just Test If The Notification Works Well"
		args.Content = notify
		ne := h.connector.CallByMethod("NotifyService.NotifyPush", args, nil)
		if ne != nil {
			log.Debugf("testNotify: %v\n", ne.Error())
		}
	}(args, reply)

	return
}
Beispiel #2
0
func (n *NotifyService) NotifyPush(args common.CommonRequest, reply *common.CommonReply) error {
	log.Debugf("NotifyPush\t:args(%+v)\n", args)
	client := net.Clients[args.PlayerId]
	if client == nil {
		log.Debugf("NotifyPush:net.Clients(%+v)\n", net.Clients)
		return errors.New("client connection not existed")
	}

	client.SendNotify(args.Content)
	return nil
}
Beispiel #3
0
func (bs *BaseService) startBusServer() (err error) {
	if bs.running {
		return errors.New("Can not start a service twice")
	}

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

	err = bs.checkIfRequestsAllAvailabe()
	if err != nil {
		return
	}

	var selfServer bus.ServerConfig
	selfServer.Type = bs.config.Server.Type
	selfServer.ServerId = bs.config.Server.Id
	selfServer.Host = bs.config.Server.Host
	selfServer.Port = bs.config.Server.Port
	selfServer.Name = bs.config.Server.Name
	selfServer.Network = bs.config.Server.Network

	bs.busServer, err = bus.StartBusServer(&selfServer)
	if err != nil {
		panic(err.Error())
	}
	log.Debugf("startBusServer:busServer(%+v)\n", *bs.busServer)

	return
}
Beispiel #4
0
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)
	}
}
Beispiel #5
0
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)
	}
}
Beispiel #6
0
func (h *Service) Auth(req common.CommonRequest, reply *common.CommonReply) (err error) {
	reply.Type = req.Type
	reply.PlayerId = 10000
	reply.Result = common.ResultSuccess
	reply.Content = common.ClientResponse{Type: reply.Type, Result: reply.Result}
	log.Debugf("Auth:req(%+v),reply(%+v)\n", req, *reply)
	return nil
}
Beispiel #7
0
// 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)
}
Beispiel #8
0
func handleResponse(client *Client) {
	defer func() {
		if x := recover(); x != nil {
			if client.Connected {
				var request ClientRequest
				request.Type = "Exception"
				request.Content = fmt.Sprint(x)
				client.Request <- request
			}
		}
		log.Debugf("Quit handleResponse : player %d\n", client.Id)
	}()

	for {
		channel, body, bytes := client.Receive()

		var response ClientResponse
		response.Content = body
		response.Data = bytes

		log.Debugf("handleResponse:player(%d),response(%+v)\n", client.Id, response)
		client.Response[channel] <- response
	}
}
Beispiel #9
0
func (client *Client) Send(channel uint32, sendbody string, sendbytes []byte) {
	client.Mutex.Lock()

	buf := new(bytes.Buffer)
	w := gzip.NewWriter(buf)
	if _, err := w.Write([]byte(sendbody)); err != nil {
		panic(err.Error())
	}
	if err := w.Close(); err != nil {
		panic(err.Error())
	}
	body := string(buf.Bytes())

	log.Debugf("%d <<< ch:%d sending %d->%d body:\n%s\n", client.Id, channel, len(sendbody), len(body), sendbody)

	var header HEADER
	header.Sign = HEADERSIGN
	header.Channel = channel
	header.Bodysize = uint32(len(body))
	header.ContentSize = uint32(len(sendbody))
	header.DataSize = uint32(len(sendbytes))

	retHeadBuf := bytes.NewBuffer(nil)
	binary.Write(retHeadBuf, binary.LittleEndian, &header)

	client.Conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
	n, err := client.Conn.Write(retHeadBuf.Bytes())
	if err != nil || n != len(retHeadBuf.Bytes()) {
		panic(err.Error())
	}

	client.Conn.SetWriteDeadline(time.Now().Add(30 * time.Second))
	n, err = client.Conn.Write([]byte(body))
	if err != nil || n != len([]byte(body)) {
		panic(err.Error())
	}

	if header.DataSize > 0 {
		client.Conn.SetWriteDeadline(time.Now().Add(30 * time.Second))
		n, err = client.Conn.Write(sendbytes)
		if err != nil || n != len(sendbytes) {
			panic(err.Error())
		}
	}

	client.Mutex.Unlock()
}
Beispiel #10
0
func (bs *BaseService) startBusStub() (err error) {
	if bs.running {
		return errors.New("Can not start a service twice")
	}

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

	err = bs.checkIfRequestsAllAvailabe()
	if err != nil {
		return
	}

	var selfServer bus.ServerConfig
	selfServer.Type = bs.config.Server.Type
	selfServer.ServerId = bs.config.Server.Id
	selfServer.Host = bs.config.Server.Host
	selfServer.Port = bs.config.Server.Port
	selfServer.Name = bs.config.Server.Name
	selfServer.Network = bs.config.Server.Network
	selfServer.Requests = bs.config.Server.Requests

	var busServer bus.ServerConfig
	busServer.Type = bs.config.Connector.Type
	busServer.ServerId = bs.config.Connector.Id
	busServer.Host = bs.config.Connector.Host
	busServer.Port = bs.config.Connector.Port
	busServer.Name = bs.config.Connector.Name
	busServer.Network = bs.config.Connector.Network

	bs.busStub, err = bus.StartBusStub(&selfServer, &busServer)
	if err != nil {
		return
	}

	log.Debugf("startBusStub:busStub(%+v)\n", *bs.busStub)
	return
}
Beispiel #11
0
func (client *Client) Receive() (channel uint32, body string, recvBytes []byte) {

	var header HEADER
	packetbuf := make([]byte, 20)
	if client.ReadDeadline > 0 {
		//client.Conn.SetReadDeadline(time.Now().Add(3 * HeartBeatRate * time.Second))
		client.Conn.SetReadDeadline(time.Now().Add(client.ReadDeadline))
	} else {
		client.Conn.SetReadDeadline(time.Time{})
	}
	n, err := client.Conn.Read(packetbuf)
	if err != nil {
		panic(err.Error())
	}

	buf := bytes.NewBuffer(packetbuf[0:n])
	binary.Read(buf, binary.LittleEndian, &header)
	if header.Sign != HEADERSIGN {
		panic("header sign not match, disconnect")
	}

	channel = header.Channel

	bytesExpected := int(header.Bodysize)
	bodyBytes := make([]byte, 0)
	bytesRead := 0

	for bytesRead < bytesExpected {
		bytes := make([]byte, bytesExpected-bytesRead)

		client.Conn.SetReadDeadline(time.Now().Add(30 * time.Second))
		n, err = client.Conn.Read(bytes)
		if err != nil {
			panic(err.Error())
		}
		bytesRead += n
		bodyBytes = append(bodyBytes, bytes[:n]...)
	}

	body = string(bodyBytes)

	{
		buf := new(bytes.Buffer)
		if _, e := buf.WriteString(body); e != nil {
			panic("received body gzip failed")
		}

		r, e := gzip.NewReader(buf)
		if e != nil {
			panic("received body gzip failed")
		}
		b, e := ioutil.ReadAll(r)
		if e != nil {
			panic("received body gzip failed")
		}
		body = string(b)

		if e := r.Close(); e != nil {
			panic("received body gzip failed")
		}
	}

	if header.ContentSize != uint32(len(body)) {
		panic("received body content size mismatch")
	}

	log.Debugf("%d >>> ch:%d receiving %d->%d body:\n%s", client.Id, channel, header.ContentSize, header.Bodysize, body)

	if header.DataSize > 0 {
		bytesExpected := int(header.DataSize)
		recvBytes := make([]byte, 0)
		bytesRead := 0

		for bytesRead < bytesExpected {
			bytes := make([]byte, bytesExpected-bytesRead)

			client.Conn.SetReadDeadline(time.Now().Add(30 * time.Second))
			n, err = client.Conn.Read(bytes)
			if err != nil {
				panic(err.Error())
			}
			bytesRead += n
			recvBytes = append(recvBytes, bytes[:n]...)
		}
	}

	return
}
Beispiel #12
0
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
		}
	}
}