예제 #1
0
// GetServer handle for server get
func GetServer0(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("key")
	callback := params.Get("callback")
	protoStr := params.Get("proto")
	res := map[string]interface{}{"ret": OK, "msg": "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
	}
	res["data"] = map[string]interface{}{"server": addrs[0]}
	return
}
예제 #2
0
// 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"] = InternalErr
		log.Error("ioutil.ReadAll() failed (%v)", err)
		return
	}
	body = string(bodyBytes)
	params := r.URL.Query()
	key := params.Get("key")
	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
	}
	node := myrpc.GetComet(key)
	if node == nil || node.Rpc == nil {
		res["ret"] = NotFoundServer
		return
	}
	client := node.Rpc.Get()
	if client == nil {
		res["ret"] = NotFoundServer
		return
	}
	rm := json.RawMessage(bodyBytes)
	msg, err := rm.MarshalJSON()
	if err != nil {
		res["ret"] = ParamErr
		log.Error("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 {
		log.Error("client.Call(\"%s\", \"%s\", &ret) error(%v)", myrpc.CometServicePushPrivate, args.Key, err)
		res["ret"] = InternalErr
		return
	}
	return
}
예제 #3
0
// 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
}