Пример #1
0
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
}
Пример #2
0
// 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)
}