コード例 #1
0
// GetServer2 handle for server get.
func GetServer2(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		http.Error(w, "Method Not Allowed", 405)
		return
	}
	params := r.URL.Query()
	key := params.Get("k")
	callback := params.Get("cb")
	protoStr := params.Get("p")
	res := map[string]interface{}{"ret": OK}
	defer retWrite(w, r, res, callback, time.Now())
	if key == "" {
		res["ret"] = ParamErr
		return
	}
	// Match a push-server with the value computed through ketama algorithm
	node := myrpc.GetComet(key)
	if node == nil {
		res["ret"] = NotFoundServer
		return
	}
	addrs, ret := getProtoAddr(node, protoStr)
	if ret != OK {
		res["ret"] = ret
		return
	}
	// give client a addr list, client do the best choice
	res["data"] = map[string]interface{}{"server": addrs}
	return
}
コード例 #2
0
ファイル: admin.go プロジェクト: youynu/gopush-cluster
// PushPrivate handle for push private message.
func PushPrivate(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method Not Allowed", 405)
		return
	}
	body := ""
	res := map[string]interface{}{"ret": OK}
	defer retPWrite(w, r, res, &body, time.Now())
	// param
	bodyBytes, err := ioutil.ReadAll(r.Body)
	if err != nil {
		res["ret"] = ParamErr
		glog.Errorf("ioutil.ReadAll() failed (%s)", err.Error())
		return
	}
	body = string(bodyBytes)
	params := r.URL.Query()
	key := params.Get("key")
	expireStr := params.Get("expire")
	if key == "" {
		res["ret"] = ParamErr
		return
	}
	expire, err := strconv.ParseUint(expireStr, 10, 32)
	if err != nil {
		res["ret"] = ParamErr
		glog.Errorf("strconv.ParseUint(\"%s\", 10, 32) error(%v)", expireStr, err)
		return
	}
	node := myrpc.GetComet(key)
	if node == nil || node.CometRPC == nil {
		res["ret"] = NotFoundServer
		return
	}
	client := node.CometRPC.Get()
	if client == nil {
		res["ret"] = NotFoundServer
		return
	}
	rm := json.RawMessage(bodyBytes)
	msg, err := rm.MarshalJSON()
	if err != nil {
		res["ret"] = ParamErr
		glog.Errorf("json.RawMessage(\"%s\").MarshalJSON() error(%v)", body, err)
		return
	}
	args := &myrpc.CometPushPrivateArgs{Msg: json.RawMessage(msg), Expire: uint(expire), Key: key}
	ret := 0
	if err := client.Call(myrpc.CometServicePushPrivate, args, &ret); err != nil {
		glog.Errorf("client.Call(\"%s\", \"%s\", &ret) error(%v)", myrpc.CometServicePushPrivate, args.Key, err)
		res["ret"] = InternalErr
		return
	}
	return
}
コード例 #3
0
// GetServer handle for server get
func GetServer(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		http.Error(w, "Method Not Allowed", 405)
		return
	}
	params := r.URL.Query()
	key := params.Get("k")
	callback := params.Get("cb")
	protoStr := params.Get("p")
	res := map[string]interface{}{"ret": OK}
	defer retWrite(w, r, res, callback, time.Now())
	if key == "" {
		res["ret"] = ParamErr
		return
	}
	proto, err := strconv.Atoi(protoStr)
	if err != nil {
		glog.Errorf("strconv.Atoi(\"%s\") error(%v)", protoStr, err)
		res["ret"] = ParamErr
		return
	}
	// Match a push-server with the value computed through ketama algorithm
	node := myrpc.GetComet(key)
	if node == nil {
		res["ret"] = NotFoundServer
		return
	}
	addrs := node.Addr[proto]
	if addrs == nil || len(addrs) == 0 {
		res["ret"] = NotFoundServer
		return
	}
	server := ""
	// Select the best ip
	if Conf.Router != "" {
		var ips []string
		for _, addr := range addrs {
			ips = append(ips, addr.Addr)
		}
		server = routerCN.SelectBest(r.RemoteAddr, ips)
		glog.V(1).Infof("select the best ip:\"%s\" match with remoteAddr:\"%s\" , from ip list:\"%v\"", server, r.RemoteAddr, ips)
	}
	if server == "" {
		glog.V(1).Infof("remote addr: \"%s\" chose the ip: \"%s\"", r.RemoteAddr, addrs[0].Addr)
		server = addrs[0].Addr
	}
	res["data"] = map[string]interface{}{"server": server}
	return
}
コード例 #4
0
ファイル: admin.go プロジェクト: Terry-Mao/gopush-cluster
// PushMultiPrivate handle for push multiple private messages.
// Because of it`s going asynchronously in this method, so it won`t return a InternalErr to caller.
func PushMultiPrivate(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method Not Allowed", 405)
		return
	}
	body := ""
	res := map[string]interface{}{"ret": OK}
	defer retPWrite(w, r, res, &body, time.Now())
	// post param
	bodyBytes, err := ioutil.ReadAll(r.Body)
	if err != nil {
		res["ret"] = InternalErr
		log.Error("ioutil.ReadAll() failed (%v)", err)
		return
	}
	body = string(bodyBytes)
	msgBytes, keys, ret := parseMultiPrivate(bodyBytes)
	if ret != OK {
		res["ret"] = ret
		return
	}
	rm := json.RawMessage(msgBytes)
	msg, err := rm.MarshalJSON()
	if err != nil {
		res["ret"] = ParamErr
		log.Error("json.RawMessage(\"%s\").MarshalJSON() error(%v)", string(msg), err)
		return
	}
	// url param
	params := r.URL.Query()
	expire, err := strconv.ParseUint(params.Get("expire"), 10, 32)
	if err != nil {
		res["ret"] = ParamErr
		log.Error("strconv.ParseUint(\"%s\", 10, 32) error(%v)", params.Get("expire"), err)
		return
	}
	// match nodes
	nodes := map[*myrpc.CometNodeInfo]*[]string{}
	for i := 0; i < len(keys); i++ {
		node := myrpc.GetComet(keys[i])
		if node == nil || node.Rpc == nil {
			res["ret"] = NotFoundServer
			return
		}
		keysTmp, ok := nodes[node]
		if ok {
			*keysTmp = append(*keysTmp, keys[i])
		} else {
			nodes[node] = &([]string{keys[i]})
		}
	}
	var fKeys []string
	//push to every node
	for cometInfo, ks := range nodes {
		client := cometInfo.Rpc.Get()
		if client == nil {
			log.Error("cannot get comet rpc client")
			fKeys = append(fKeys, *ks...)
			continue
		}
		args := &myrpc.CometPushPrivatesArgs{Msg: json.RawMessage(msg), Expire: uint(expire), Keys: *ks}
		resp := myrpc.CometPushPrivatesResp{}
		if err := client.Call(myrpc.CometServicePushPrivates, args, &resp); err != nil {
			log.Error("client.Call(\"%s\", \"%v\", &ret) error(%v)", myrpc.CometServicePushPrivates, args.Keys, err)
			fKeys = append(fKeys, *ks...)
			continue
		}
		log.Debug("fkeys len(%d) addr:%v", len(resp.FKeys), cometInfo.RpcAddr)
		fKeys = append(fKeys, resp.FKeys...)
	}
	res["ret"] = OK
	if len(fKeys) != 0 {
		res["data"] = map[string]interface{}{"fk": fKeys}
	}
	return
}