Example #1
0
func (s *Server) RegisteAsLocalService(recv interface{}) {
	t := reflect.TypeOf(recv)
	v := reflect.ValueOf(recv)
	numMethod := t.NumMethod()
	sName := v.Type().Name()
	for index := 0; index < numMethod; index++ {
		methodName := t.Method(index).Name
		if handler, ok := v.Method(index).Interface().(func(*sessionService.SimpleSession, map[string]interface{}) map[string]interface{}); ok == true {
			s.handlers[sName+"."+methodName] = handler
			seelog.Infof("<%v> Registe local service<%v>'s method<%v>", context.GetContext().GetServerID(), v.Type().Name(), methodName)
		} else {
			seelog.Warnf("<%v> Registe local service <%v>'s method<%v> error", context.GetContext().GetServerID(), v.Type().Name(), methodName)
		}
	}
}
Example #2
0
func main() {

	if len(os.Args) < 3 {
		fmt.Fprintf(os.Stderr, "too few args,args form: <host port>\n")
		os.Exit(1)
	}
	host := os.Args[1]
	port, err := strconv.Atoi(os.Args[2])
	if err != nil {
		fmt.Fprintf(os.Stderr, "invalid port,need integer type,your input port: <port>\n", os.Args[2])
		os.Exit(1)
	}
	ctx := context.GetContext()
	currentServer := make(map[string]interface{})
	currentServer["id"] = "connector-1"
	currentServer["serverType"] = "connector"
	currentServer["host"] = "127.0.0.1"
	currentServer["port"] = 8888
	ctx.CurrentServer = currentServer
	defer seelog.Flush()

	tcp_cnct := tcp_connector.NewTcpConnector(host, port, nil)

	tcp_cnct.RegistNewConnCB(NewConnCB)
	tcp_cnct.RegistNewMsgCB(NewMsgCB)
	tcp_cnct.Start()
	ch := make(chan int)
	<-ch
}
func (ts *TcpSocket) Disconnect() {
	seelog.Debugf("<%v> Disconnect sid<%v>", context.GetContext().GetServerID(), ts.id)
	if ts.status == connector.ST_CLOSED {
		return
	}

	ts.status = connector.ST_CLOSED
	ts.socket.Close()
}
func NewChannelRpcServer() *ChannelRpcServer {
	ctx := context.GetContext()

	coCnct, ok := ctx.GetComponent("coconnector").(*coconnector.CoConnector)
	if ok == false {
		coCnct = coconnector.NewCoConnector(ctx)
	}

	return &ChannelRpcServer{coCnct}
}
func (crs *ChannelRpcServer) PushMessage(args map[string]interface{}, reply interface{}) error {
	route, _ := args["route"].(string)
	msg, ok1 := args["msg"].(map[string]interface{})
	if ok1 == false {
		seelog.Error("Invalid or empty message")
		return errors.New("Invalid or empty message")
	}

	coSess, ok2 := context.GetContext().GetComponent("cosession").(*cosession.CoSession)

	if ok2 == false {
		seelog.Critical("Failed to get component<cosession>")
		os.Exit(1)
	}

	uids, ok3 := args["uids"].([]string)
	if ok3 == false {
		seelog.Error("Failed to get uids")
		return errors.New("Failed to get uids")
	}

	sids := make([]uint32, 0, 16)
	for _, uid := range uids {
		sessions := coSess.GetSessionsByUID(uid)

		if sessions == nil {
			seelog.Warnf("Failed to push message to uid<%v> because of nil sessions", uid)
			continue
		}

		for _, session := range sessions {
			sids = append(sids, session.Id)
		}
	}

	seelog.Debugf("<%v> push messages<%v> to uids<%v> with sessions<%v>", context.GetContext().GetServerID(), msg, uids, sids)

	//XXX:调用coconnector的send方法发送.
	crs.coCnct.Send("", route, msg, sids)
	return nil

}
Example #6
0
func NewCoServer() *CoServer {
	ctx := context.GetContext()
	coServ, ok := ctx.GetComponent("coserver").(*CoServer)
	if ok == true {
		return coServ
	}
	serv := server.NewServer()
	coServ = &CoServer{serv}
	seelog.Infof("<%v> component server created", ctx.GetServerID())
	return coServ
}
func NewSessionRpcServer() *SessionRpcServer {
	ctx := context.GetContext()

	sessionService, ok := ctx.GetComponent("cosession").(*cosession.CoSession)

	if ok == false || sessionService == nil {
		sessionService = cosession.NewCoSession()
	}

	return &SessionRpcServer{sessionService}
}
func (srs *SessionRpcServer) Start() {
	ctx := context.GetContext()
	coRpcS, ok := ctx.GetComponent("corpcserver").(*corpcserver.CoRpcServer)

	if ok == false {
		coRpcS = corpcserver.NewCoRpcServer()
	}

	seelog.Infof("frontendserver<%v> SessionRpcServer start,registe service to rpc server", ctx.GetServerID())
	// srs := NewSessionRpcServer()
	coRpcS.RegisteService(srs)
}
/// 创建新的ChannelService,ChannelService管理用户创建的所有Channel,并代理用户对Channel的操作,
/// 用户发送给一个Channel里所有session的消息会通过rpc调用发送给对应的前端服务器,并通过前端服务
/// 器推送给客户端.
func NewChannelService() *ChannelService {
	ctx := context.GetContext()

	coRpcClient, ok := ctx.GetComponent("corpcclient").(*corpcclient.CoRpcClient)

	if ok == false {
		coRpcClient = corpcclient.NewCoRpcClient()
	}

	channels := make(map[string]*Channel)

	return &ChannelService{ctx, coRpcClient, channels}
}
func (crs *ChannelRpcServer) Start() {
	ctx := context.GetContext()
	coRpcS, ok := ctx.GetComponent("corpcserver").(*corpcserver.CoRpcServer)

	if ok == false {
		coRpcS = corpcserver.NewCoRpcServer()
	}

	seelog.Info("ChannelRpcServer start,registe service to rpcserver")
	// srs := NewSessionRpcServer()
	coRpcS.RegisteService(crs)

}
Example #11
0
func NewCoMonitor() *CoMonitor {
	ctx := context.GetContext()
	coMonitor, ok := ctx.GetComponent("comonitor").(*CoMonitor)
	if ok == true {
		return coMonitor
	}

	mcs := pomelo_admin.NewMonitorConsoleService(ctx)
	coMonitor = &CoMonitor{mcs}
	seelog.Infof("<%v> component CoMonitor created...", ctx.GetServerID())
	ctx.RegisteComponent("comonitor", coMonitor)
	return coMonitor
}
/// 通过session id从前端服务器踢除用户连接,通过rpc调用前端服务器的同样操作.
///
/// @param frontendid 前端服务器id
/// @param sid session id
/// @reason 作为踢除用户连接时发送给用户端的提示信息.
/// @return 无返回值
func (bss *BackendSessionService) KickBySID(frontendid string, sid uint32, reason string) {
	seelog.Tracef("frontendid<%v>,sid<%v>", frontendid, sid)

	method := "SessionRpcServer.KickBySID"

	args := make([]interface{}, 2)

	args[0] = sid
	args[1] = reason
	if err := bss.rpcCient.RpcCall(frontendid, method, args, nil); err != nil {
		seelog.Errorf("<%v> KickBySID error<%v>", context.GetContext().GetServerID(), err.Error())
	}
}
/// 创建新的SessionService.
///
/// @param opts 指定创建SessionService的选项,选项是name:value的形式
/// @return *SessionService
func NewSessionService(opts map[string]interface{}) *SessionService {
	if nil == opts {
		opts = make(map[string]interface{})
	}
	sessions := make(map[uint32]*Session)
	uidmap := make(map[string][]*Session)

	multibind := opts["multiBind"] != nil && (opts["multiBind"].(string) != "")
	rwMutexS := new(sync.RWMutex)
	rwMutexUM := new(sync.RWMutex)
	seelog.Infof("frontendserver<%v> create sessionservice with opts<%v>", context.GetContext().GetServerID(), opts)
	return &SessionService{sessions, uidmap, multibind, opts, rwMutexS, rwMutexUM}
}
/// 发送消息到groups中的所有用户.
///
/// @route 路由
/// @param msg 发送的消息
/// @param groups frontendID-> uids的映射
func (cs *ChannelService) sendMsgByGroup(route string, msg map[string]interface{}, groups map[string][]string) {
	seelog.Debugf("<%v> channelService sendMsgByGroup with route<%v> msg<%v> groups<%v>", cs.ctx.GetServerID(), route, msg, groups)

	args := make(map[string]interface{})

	args["route"] = route
	args["msg"] = msg

	coChanRpcS, ok := context.GetContext().GetComponent("cochannelrpcserver").(*cochannelrpcserver.CoChannelRpcServer)
	if ok == false {
		seelog.Error("Fail to get CoChannelRpcServer")
		return
	}

	sendMsg := func(serverid string) {
		if cs.ctx.GetServerID() == serverid {
			//TODO:直接调用channelRpcServer相关方法,无需rpc
			if err := coChanRpcS.PushMessage(args, nil); err != nil {
				seelog.Errorf("Fail to invoke PushMessage to send msg,error<%v>", err.Error())
				return
			}

		} else {
			//TODO:发起rpc调用.
			if err := cs.coRpcClient.RpcCall(serverid, "ChannelRpcServer.PushMessage", args, nil); err != nil {
				seelog.Errorf("<%v> fail to invoke rpc PushMessage error<%v>", context.GetContext().GetServerID(), err.Error())
				return
			}
		}
	}

	for frontendID, uids := range groups {
		//TODO:逐个发送msg.
		seelog.Infof("<%v> PushMessage to uids<%v> connected to frontend<%v>", context.GetContext().GetServerID(), uids, frontendID)
		args["uid"] = uids
		sendMsg(frontendID)
	}
}
func (bss *BackendSessionService) PushAllOpts(frontendid string, sid uint32, settings map[string]interface{}) {
	seelog.Tracef("Push all opts to <%v> with sid<%v>", frontendid, sid)

	args := make(map[string]interface{})

	args["sid"] = sid
	args["settings"] = settings

	method := "SessionRpcServer.PushAllOpts"

	if err := bss.rpcCient.RpcCall(frontendid, method, &args, nil); err != nil {
		seelog.Errorf("<%v> PushAllOpts with sid<%v> to frontend<%v> error<%v>", context.GetContext().GetServerID(), sid, frontendid, err.Error())
	}
}
Example #16
0
func NewCoChannel() *CoChannel {
	ctx := context.GetContext()

	coChan, ok := ctx.GetComponent("cochannel").(*CoChannel)
	if ok == true {
		return coChan
	}
	chanS := channelService.NewChannelService()
	coChan = &CoChannel{chanS}
	ctx.RegisteComponent("cochannel", coChan)
	seelog.Info("CoChannel create successfully")
	return coChan

}
func NewCoBackendSession() *CoBackendSession {
	ctx := context.GetContext()

	coBS, ok := ctx.GetComponent("cobackendsession").(*CoBackendSession)
	if ok == true {
		return coBS
	}
	bss := backendSessionService.NewBackendSessionService(ctx)
	coBS = &CoBackendSession{bss}

	ctx.RegisteComponent("cobackendsession", coBS)

	return coBS
}
func NewCoConnection() *CoConnection {
	ctx := context.GetContext()
	coconn, ok := ctx.GetComponent("coconnection").(*CoConnection)
	if ok == true {
		return coconn
	}

	cs := connectionService.NewConnectionService(ctx.GetServerID())

	coconn = &CoConnection{cs, ctx}
	ctx.RegisteComponent("coconnection", coconn)

	seelog.Infof("CoConnetion create successfully")
	return coconn
}
func NewCoChannelRpcServer() *CoChannelRpcServer {

	ctx := context.GetContext()

	coChanRS, ok := ctx.GetComponent("cochannelrpcserver").(*CoChannelRpcServer)
	if ok == false {
		seelog.Infof("CoChannelRpcServer not found,create new...")
		chanRpcS := channelRpcServer.NewChannelRpcServer()
		coChanRS = &CoChannelRpcServer{chanRpcS}
		ctx.RegisteComponent("cochannelrpcserver", coChanRS)
	}

	seelog.Infof("CoChannelRpcServer create successfully")
	return coChanRS
}
Example #20
0
/// 创建CoSession.
func NewCoSession() *CoSession {
	ctx := context.GetContext()

	cosess, ok := ctx.GetComponent("cosession").(*CoSession)
	if ok == true {
		return cosess
	}
	ss := sessionService.NewSessionService(ctx.AllOpts["cosession"])

	cosess = &CoSession{ss}

	ctx.RegisteComponent("cosession", cosess)
	seelog.Info("CoSession create successufully")
	return cosess
}
Example #21
0
func NewServer() *Server {
	ctx := context.GetContext()

	coRpcS, ok1 := ctx.GetComponent("corpcserver").(*corpcserver.CoRpcServer)
	if ok1 == false {
		coRpcS = corpcserver.NewCoRpcServer()
	}

	coRpcC, ok2 := ctx.GetComponent("corpcclient").(*corpcclient.CoRpcClient)
	if ok2 == false {
		coRpcC = corpcclient.NewCoRpcClient()
	}
	handlers := make(map[string]func(*sessionService.SimpleSession, map[string]interface{}) map[string]interface{})
	return &Server{ctx, coRpcS, coRpcC, handlers}
}
/// 创建CoSessionRpcServer组建.
func NewCoSessionRpcServer() *CoSessionRpcServer {
	ctx := context.GetContext()
	coSRS, ok := ctx.GetComponent("cosessionrpcserver").(*CoSessionRpcServer)

	if ok == true {
		return coSRS
	}

	srs := sessionRpcServer.NewSessionRpcServer()
	coSRS = &CoSessionRpcServer{srs}

	ctx.RegisteComponent("cosessionrpcserver", coSRS)

	return coSRS
}
/// 解除用户id到session id的绑定,该操作会通过rpc调用影响前端服务器.
///
/// @param frontendid 前端服务器id
/// @param sid session id
/// @param uid 用户id
func (bss *BackendSessionService) UnbindUID(frontendid string, sid uint32, uid string) {
	seelog.Tracef("Unbind uid<%v> with session id<%v>", uid, sid)

	args := make([]interface{}, 2)

	args[0] = sid
	args[1] = uid

	method := "SessionRpcServer.UnbindUID"

	if err := bss.rpcCient.RpcCall(frontendid, method, &args, nil); err != nil {

		seelog.Errorf("<%v> UnbindUID uid<%v>  with sid<%v> error<%v>", context.GetContext().GetServerID(), uid, sid, err.Error())
	}
}
func NewCoRpcServer() *CoRpcServer {
	ctx := context.GetContext()

	coRpcS, ok := ctx.GetComponent("corpcserver").(*CoRpcServer)
	if ok == true {
		return coRpcS
	}

	host, _ := ctx.CurrentServer["host"].(string)
	port, _ := ctx.CurrentServer["port"].(int)
	rpcS := rpcserver.NewRpcServer(host, port)

	coRpcS = &CoRpcServer{rpcS}
	ctx.RegisteComponent("corpcserver", coRpcS)
	seelog.Info("CoRpcServer create successfully")
	return coRpcS
}
/// 将设置sid标识的session的属性同步到前端服务器.
///
/// @param frontendid 前端服务器id
/// @param sid session id
/// @param key 属性名
/// @param value 属性值
func (bss *BackendSessionService) PushOpt(frontendid string, sid uint32, key string, value interface{}) {
	seelog.Tracef("Push opt to <%v> with sid<%v>,key<%v>,value<%v>", frontendid, sid, key, value)

	args := make(map[string]interface{})

	args["sid"] = sid
	args["key"] = key
	args["value"] = value

	method := "SessionRpcServer.PushOpt"

	if err := bss.rpcCient.RpcCall(frontendid, method, &args, nil); err != nil {

		seelog.Errorf("<%v> PushOpt with sid<%v> to frontend<%v> error<%v>", context.GetContext().GetServerID(), sid, frontendid, err.Error())
	}

}
Example #26
0
func main() {
	ctx := context.GetContext()
	allOpts := make(map[string]map[string]interface{})
	cosessOpts := make(map[string]interface{})

	//指定同一个uid可以绑定多个session
	cosessOpts["multiBind"] = "yes"
	allOpts["cosession"] = cosessOpts
	ctx.AllOpts = allOpts
	defer seelog.Flush()
	currentServer := make(map[string]interface{})
	currentServer["id"] = "connector-1"
	currentServer["serverType"] = "connector"
	currentServer["host"] = "127.0.0.1"
	currentServer["port"] = 8888
	ctx.CurrentServer = currentServer
	cosess := cosession.NewCoSession()
	cosessRS := cosessionrpcserver.NewCoSessionRpcServer()
	corpcS := corpcserver.NewCoRpcServer()

	// 启动cosession,cosessionrpcserver,corpcserver
	cosess.Start()
	cosessRS.Start()
	corpcS.Start()

	cosess.CreateSession(1, "connector-1", nil)
	cosess.BindUID("Zhang San", 1)
	cosess.CreateSession(2, "connector-1", nil)
	cosess.BindUID("Li Si", 2)
	cosess.CreateSession(3, "connector-1", nil)
	cosess.BindUID("Li Si", 3)
	cosess.CreateSession(4, "connector-1", nil)
	cosess.BindUID("Wang Wu", 4)

	ch := make(chan int)
	<-ch
}
Example #27
0
func (s *Server) GlobalHandler(msg map[string]interface{}, session *sessionService.SimpleSession, sendCB func(string, string, map[string]interface{}, []uint32)) {
	frontendID := s.ctx.GetServerID()
	route, _ := msg["route"].(string)
	record := parseRoute(route)
	if record == nil {
		seelog.Errorf("receive invalid route<%v>, route format must be<serverType.handler.method>", route)
		return
	}
	handlerMethodName := record.handler + "." + record.method
	if context.GetContext().GetServerType() == record.serverType {
		///调用本地方法处理.
		seelog.Infof("<%v> receive local handler<%v> request", frontendID, handlerMethodName)
		if handlerMethod, ok := s.handlers[handlerMethodName]; ok == true {
			replyMsg := handlerMethod(session, msg)
			seelog.Debugf("<%v> local handler<%v> reply msg<%v>", frontendID, handlerMethodName, replyMsg)
			sids := make([]uint32, 1)
			sids[0] = session.Id
			reqID, _ := replyMsg["reqID"].(string)
			rroute, _ := replyMsg["route"].(string)
			msgBody, _ := replyMsg["msg"].(map[string]interface{})
			sendCB(reqID, rroute, msgBody, sids)
		} else {
			seelog.Errorf("<%v> request local handler<%v> error", frontendID, handlerMethodName)
		}
	} else {
		///rpc调用远端方法

		servID := s.ctx.GetServerIDByType(record.serverType)
		seelog.Infof("<%v> invoke remote handler<%v> request of <%v>", frontendID, handlerMethodName, servID)
		reply := make(map[string]interface{})
		if err := s.coRpcC.RpcCall(servID, handlerMethodName, msg, &reply); err != nil {
			seelog.Errorf("<%v> rpc call<%v> error<%v>", frontendID, handlerMethodName, err.Error())
		}
	}

}
func (bss *BackendSessionService) Start() {
	seelog.Infof("server<%v> start BackendSessionService", context.GetContext().GetServerID())
}
Example #29
0
func (cs *CoSession) Start() {
	ctx := context.GetContext()
	seelog.Infof("frontendserver<%v> cosession start", ctx.GetServerID())
}
/// 创建新的TcpConnector
func NewTcpConnector(host string, port string, opts map[string]string) *TcpConnector {
	regE := make(map[string]func(args ...interface{}))
	return &TcpConnector{host, port, opts, regE, context.GetContext()}
}