func StartChannelSenderStage0(channel_name string, stage0_channel, stage1_channel chan *lib.PostMessage) chan bool { close_chan := make(chan bool) go func() { defer func() { if err := recover(); err != nil { utils.Log.Println(err) debug.PrintStack() } }() var post_message *lib.PostMessage var new_post_message *lib.PostMessage channel := GetChannel(channel_name) for { select { case <-close_chan: utils.Log.Printf("Channel [%s] SenderStage0 has quit...\n", channel_name) close_chan <- true return case post_message = <-stage0_channel: post_message.Lock = new(isync.SpinLock) stage1_channel <- post_message channel.LastPostUpdate = time.Now().Unix() if channel.MQTTMessageChan != nil { new_post_message = CopyMessage(channel, post_message) channel.MQTTMessageChan <- new_post_message } if ServerDebug { utils.Log.Println("ChannelSenderStage0: send post_message to stage1_channel", post_message) } } } }() return close_chan }
// 处理POST消息 func MessagePostHandler(w http.ResponseWriter, req *http.Request) { defer func() { if err := recover(); err != nil { utils.Log.Println(err) debug.PrintStack() } }() var channel_name string var channel *Channel var err error var buf []byte w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "channel, tourid, tag") w.Header().Set("Access-Control-Allow-Credentials", "true") channel_name = req.Header.Get("channel") if channel_name == "" { utils.Log.Printf("[%s] channel name not in header\n", req.RemoteAddr) http.Error(w, "channel name not in header", 400) return } // use byte pool buffer := byte_pool.Checkout() defer buffer.Close() buffer.ReadFrom(req.Body) body := buffer.Bytes() channel = GetChannel(channel_name) //post_message := channel.PostMessagePool.Get().(*lib.PostMessage) post_message := new(lib.PostMessage) err = ffjson.Unmarshal(body, post_message) if err != nil { utils.Log.Printf("[%s] Unmarshal json failed: [%s], channel: [%s]\n", req.RemoteAddr, err, channel_name) http.Error(w, "Unmarshal json failed", 500) return } if channel.PrepareClose == true { utils.Log.Printf("[%s] Channel: [%s] will be closed.\n", req.RemoteAddr, channel_name) http.Error(w, "channel will be closed or not exists", 500) return } message_id := utils.MakeRandomID() post_message.MessageID = message_id send_finished := false if post_message.Delay == 0 { send_finished = PostMessage(channel, post_message) } else { go PostMessage(channel, post_message) send_finished = true } post_reply := channel.PostReplyPool.Get().(*lib.PostReply) if send_finished { post_reply.Result = 0 post_reply.MessageID = message_id } else { post_reply.Result = 1 post_reply.MessageID = "message buffer of channel is full." } buf, err = ffjson.Marshal(*post_reply) if err != nil { utils.Log.Printf("[%s] Marshal JSON failed: [%s], channel: [%s]\n", req.RemoteAddr, err, channel_name) http.Error(w, "Marshal json failed", 500) return } if ServerDebug { utils.Log.Printf("Got message from [%s], message: [%s], message_id: [%s], channel: [%s]\n", req.RemoteAddr, string(body), message_id, channel_name) } w.Header().Set("Content-Type", "application/json") w.Write(buf) channel.PostReplyPool.Put(post_reply) ffjson.Pool(buf) }