func (p *protocol) SUB(client *client, params [][]byte) ([]byte, error) { if atomic.LoadInt32(&client.State) != StateInit { return nil, util.NewFatalClientErr(nil, "E_INVALID", "cannot SUB in current state") } if client.HeartbeatInterval <= 0 { return nil, util.NewFatalClientErr(nil, "E_INVALID", "cannot SUB with heartbeats disabled") } log.Printf("receive params on sub %s", params) if len(params) < 1 { return nil, util.NewFatalClientErr(nil, "E_INVALID", "SUB insufficient number of parameters") } //TODO FIXME str_channel_id := string(params[1]) channel_id, err := strconv.ParseInt(str_channel_id, 10, 64) //TODO need validate channel_id if err != nil { return nil, util.NewFatalClientErr(nil, "E_INVALID", "invalid channel id ") } client_id, err := strconv.ParseInt(client.ClientID, 10, 64) if err != nil { log.Printf("invalid client id [%s] err: %s", client.ClientID, err) return nil, util.NewFatalClientErr(nil, "E_INVALID", "invalid client id ") } channel, err := model.FindChannelByID(channel_id) if err != nil || channel == nil { return nil, util.NewFatalClientErr(nil, "E_INVALID", "invalid channel id ") } device, err := model.FindDeviceByID(client_id) if err != nil || device == nil { log.Printf("invalid client id [%d] err: %s", client_id, err) return nil, util.NewFatalClientErr(nil, "E_INVALID", "invalid client id ") } //TODO send subscribe event sub := &model.Subscribe{ ChannelID: channel_id, DeviceID: client_id, DeviceType: device.DeviceType, CreatedAt: time.Now().UnixNano(), UpdatedAt: time.Now().UnixNano(), } err = model.SaveOrUpdateSubscribe(sub) if err != nil { return nil, util.NewFatalClientErr(nil, "internal error", "save subscribe error") } p.context.broker.AddClient(client.ClientID, str_channel_id, client) log.Printf("INFO: clientId %d sub channel %s success ", client.ClientID, channel_id) // touch devie online model.TouchDeviceOnline(client_id) // should send client connected eventsf log.Printf("INFO: SetClientConn clientID=%s, broker_addr=%s", client.ClientID, client.LocalAddr().String()) err = model.SetClientConn(client.ClientID, client.LocalAddr().String()) if err != nil { return nil, util.NewFatalClientErr(nil, "internal error", "save subscribe error") } // increase channel sub count // add client to channel sub list // topic := p.context.broker.GetTopic(topicName) // channel := topic.GetChannel(channelName) // channel.AddClient(client.ID, client) atomic.StoreInt32(&client.State, StateSubscribed) client.SubChannel = str_channel_id go p.checkOfflineMessage(client) // client.Channel = channel // update message pump // client.SubEventChan <- channel return okBytes, nil }
// curl -X POST http://localhost:4171/registration?serial_no=SOHUNO20140401XX&device_type=3&device_name=搜狐Android测试机 func (s *httpServer) registerHandler(w http.ResponseWriter, req *http.Request) { log.Printf("INFO: request %s ", req.URL.RawQuery) // if req.Method != "POST" { // util.ApiResponse(w, 405, "METHOD_NOT_SUPPORT", nil) // return // } reqParams, err := url.ParseQuery(req.URL.RawQuery) if err != nil { log.Printf("ERROR: failed to parse request params - %s", err.Error()) util.ApiResponse(w, 400, "INVALID_REQUEST", nil) return } serial_no := reqParams.Get("serial_no") if len(serial_no) == 0 { util.ApiResponse(w, 400, "serial_no is required", nil) return } device_name := reqParams.Get("device_name") // device_type, err := strconv.ParseInt(reqParams.Get("device_type"), 10, 8) // if device_type != model.Android { // util.ApiResponse(w, 400, "INVALID_DEVICE_TYPE", nil) // return // } var device *model.Device = nil deviceID, err := model.FindDeviceIDBySerialNO(serial_no) log.Printf("INFO: FindDeviceIDBySerialNO %s result %s", serial_no, deviceID) if err == nil && deviceID != 0 { device, err = model.FindDeviceByID(deviceID) // log.Printf("INFO: FindDeviceByID %d result %#v", deviceID, device) if err != nil || device == nil { log.Printf("ERROR: FindDeviceByID error %s", err) util.ApiResponse(w, 500, "INTERNAL_ERROR", nil) return } } // log.Printf("INFO: exist_device %#v", device) if device == nil { device = &model.Device{ ID: <-s.context.api.idChan, SerialNO: serial_no, DeviceName: device_name, DeviceType: int8(3), //int8(device_type), CreatedAt: time.Now().UnixNano(), OnlineTimestamp: time.Now().UnixNano(), } err = model.SaveDevice(device) if err != nil { log.Printf("ERROR: SaveDevice %s error %s", device, err) util.ApiResponse(w, 500, "INTERNAL_ERROR", nil) return } } else { } data := make(map[string]interface{}) data["broker"] = "b1.zhan.sohu.com" data["device_id"] = device.ID log.Printf("INFO: regiest success %s", serial_no) util.ApiResponse(w, 200, "OK", data) }