You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS平台SocketRocket库MQTT over WebSocket主题订阅方法咨询

Hey there! Let's figure out how to subscribe to MQTT topics using SocketRocket.

First off, it’s key to understand that SocketRocket is just a low-level WebSocket client—it doesn’t wrap MQTT protocol logic for you. MQTT over WebSocket works by sending MQTT’s binary protocol packets over the established WebSocket connection, so you’ll need to manually construct those packets yourself.

Here’s a step-by-step solution:

1. Build the MQTT Subscribe Packet

MQTT has a specific binary format for subscription requests. Below is a helper function to construct a valid MQTT 3.1.1 subscribe packet (adjust if you’re using MQTT 5.0):

func buildMQTTSubscribePacket(topic: String, qos: UInt8 = 0) -> Data {
    var packet = Data()
    
    // Fixed header: Subscribe packet type (0x82) with default flags
    let fixedHeader: UInt8 = 0x82
    packet.append(fixedHeader)
    
    // Variable header: Packet ID (use a unique value for each request)
    let packetId: UInt16 = 1
    packet.append(UInt8(packetId >> 8)) // High byte
    packet.append(UInt8(packetId & 0xFF)) // Low byte
    
    // Payload: Topic name + QoS level
    let topicData = topic.data(using: .utf8)!
    let topicLength = UInt16(topicData.count)
    // Append topic length (2 bytes)
    packet.append(UInt8(topicLength >> 8))
    packet.append(UInt8(topicLength & 0xFF))
    // Append topic data
    packet.append(topicData)
    // Append QoS level (1 byte)
    packet.append(qos)
    
    // Calculate and insert remaining length (MQTT's special encoding)
    var remainingLength = packet.count - 1 // Subtract fixed header byte
    var remainingLengthBytes = Data()
    repeat {
        var byte = UInt8(remainingLength % 128)
        remainingLength /= 128
        if remainingLength > 0 {
            byte |= 0x80
        }
        remainingLengthBytes.append(byte)
    } while remainingLength > 0
    
    // Insert remaining length right after the fixed header
    packet.insert(contentsOf: remainingLengthBytes, at: 1)
    
    return packet
}

2. Send the Subscribe Packet

Once your WebSocket connection is open, use SocketRocket to send the constructed packet:

func webSocketDidOpen(_ webSocket: SRWebSocket!) {
    print("SRWebSocket webSocketDidOpen")
    
    // Customize your topic and QoS level here
    let subscribePacket = buildMQTTSubscribePacket(topic: "your/target/topic", qos: 0)
    webSocket.send(subscribePacket)
}

3. Handle MQTT Responses and Messages

You’ll need to parse incoming MQTT packets to confirm subscriptions and receive messages. Add this to your SRWebSocketDelegate:

func webSocket(_ webSocket: SRWebSocket!, didReceiveMessage message: Any!) {
    guard let mqttData = message as? Data else {
        print("Received non-binary MQTT message")
        return
    }
    parseMQTTPacket(data: mqttData)
}

private func parseMQTTPacket(data: Data) {
    let packetType = (data[0] & 0xF0) >> 4
    
    switch packetType {
    case 0x09: // SUBACK: Subscription acknowledgment
        let packetId = UInt16(data[2]) << 8 | UInt16(data[3])
        let grantedQoS = data[4]
        print("Subscribed successfully! Packet ID: \(packetId), Granted QoS: \(grantedQoS)")
    case 0x03: // PUBLISH: Incoming message from broker
        // Parse topic
        let topicLength = UInt16(data[2]) << 8 | UInt16(data[3])
        let topicRange = 4..<4+Int(topicLength)
        guard let topic = String(data: data.subdata(in: topicRange), encoding: .utf8) else {
            print("Failed to parse topic")
            return
        }
        
        // Parse payload (adjust start index if QoS > 0, which adds a packet ID)
        let qosLevel = (data[0] & 0x06) >> 1
        var payloadStart = 4 + Int(topicLength)
        if qosLevel > 0 {
            payloadStart += 2
        }
        let payloadData = data.subdata(in: payloadStart..<data.count)
        if let payload = String(data: payloadData, encoding: .utf8) {
            print("Received message on topic \(topic): \(payload)")
        }
    default:
        print("Unknown MQTT packet type: \(packetType)")
    }
}

A few quick notes:

  • Make sure your packet IDs are unique if you send multiple subscription requests.
  • If you’re using MQTT 5.0, the packet format has additional fields (like properties) that you’ll need to account for.
  • Double-check that your broker supports MQTT over WebSocket and that your topic is correctly formatted.

内容的提问来源于stack exchange,提问作者yusufonderd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:59:51