Search code examples
iosswiftflaskapache-kafkamobile-application

How to integrate Kafka consumer to mobile app through a web server as an intermediate layer?


I'm working on a mobile app where a notification will appear when the kafka producer sends one. I'm using kafka-python framework to consume the message. I'm not sure how to integrate the consumer code to my mobile app. I'm not really sure how to use a websocket on the backend and integrate it to the mobile app. So far I was trying this:

kafkaproducer:

bin/kafka-console-producer.sh --broker-list localhost:9092 --topic Hello-Kafka

consumer.py:

from kafka import KafkaConsumer
from flask import Flask
import json

new_msg = ""
app = Flask(__name__)
@app.route('/')
def hello_world():
     return new_msg

consumer = KafkaConsumer('Hello-Kafka',bootstrap_servers='localhost:9092')
for msg in consumer:
    if(len(msg.value.decode("utf-8"))!=0):
        new_msg = msg.value.decode("utf-8")
        app.run()

kafkaConsumer(value_deserializer=lambda m: json.loads(m.decode('ascii')))

mobileapp.swift:

import UIKit

class ViewController: UIViewController {

    let myNotification = Notification.Name(rawValue:"MyNotification")

    override func viewDidLoad() {
        super.viewDidLoad()

        let nc = NotificationCenter.default
        nc.addObserver(forName:myNotification, object:nil, queue:nil, using:catchNotification)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let nc = NotificationCenter.default
        nc.post(name:myNotification,
                object: nil,
                userInfo:["message":"Hello there!", "date":Date()])
    }

    func catchNotification(notification:Notification) -> Void {
        print("Catch notification")

        guard let userInfo = notification.userInfo,
            let message  = userInfo["message"] as? String,
            let date     = userInfo["date"]    as? Date else {
                print("No userInfo found in notification")
                return
        }

        let alert = UIAlertController(title: "Notification!",
                                      message:"\(message) received at \(date)",
            preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}

Right now, I'm able to send only one message to the browser after consuming from kafka. How can integrate this to mobile app and so that I can send every message that I consume to the app?


Solution

  • You might want to consider using one of the existing proxy/gateway implementations for Kafka to websockets such as the websocket proxy from Microsoft here https://github.com/Microsoft/kafka-proxy-ws or the Akka-Http WebSocket based service from Landoop here https://github.com/Landoop/kafka-ws