Rehberler

WebSocket Üzerinden MQTT: Tarayıcıdan Bağlanmak

WebSocket üzerinden MQTT: tarayıcılar neden buna ihtiyaç duyar, ws ve wss farkı, /mqtt path’i, yaygın portlar, mixed content hataları ve MQTT.js örneği.

Güncellendi · 7 dk okuma

MQTT normalde 1883 portunda (TLS ile 8883) ham bir TCP bağlantısı üzerinden çalışır. Tarayıcılar ham TCP soketleri açamaz; bu yüzden bir web uygulaması MQTT’yi bu şekilde konuşamaz. Çözüm WebSocket üzerinden MQTT’dir: aynı MQTT paketleri, her tarayıcının desteklediği bir WebSocket bağlantısı içinde taşınır. Bu rehber bunun nasıl çalıştığını ve çoğu kişiyi zorlayan hatalardan nasıl kaçınacağınızı açıklıyor.

Tarayıcıların neden WebSocket’e ihtiyacı var?

Güvenlik nedeniyle bir web sayfasındaki JavaScript ağ bağlantılarını yalnızca tarayıcı API’leri üzerinden kurabilir — fetch, XMLHttpRequest, WebSocket, WebRTC ve WebTransport. Bunların hiçbiri 1883 portuna rastgele bir TCP bağlantısı açamaz. WebSocket’ler MQTT için doğal bir seçimdir, çünkü uzun ömürlü, çift yönlü, ikili (binary) bir kanal sağlarlar — MQTT’nin tam olarak ihtiyaç duyduğu şey.

WebSocket kullanmak yalnızca tarayıcılar için değildir. Şu durumlarda da işe yarar:

  • bir firewall veya kurumsal proxy yalnızca 80 ve 443 portlarındaki web trafiğine izin veriyorsa;
  • MQTT’nin HTTP servislerinizle aynı load balancer’ı veya reverse proxy’yi paylaşmasını istiyorsanız;
  • canlı cihaz verilerini gösteren bir pano, yönetim aracı veya mobil web uygulaması geliştiriyorsanız.

WebSocket üzerinden MQTT nasıl çalışır?

  1. Client bir HTTP(S) bağlantısı açar ve wss://broker.emqx.io:8084/mqtt gibi bir URL’ye, mqtt alt protokolünü (subprotocol) talep eden bir WebSocket upgrade isteği gönderir.
  2. Broker 101 Switching Protocols ile yanıt verir ve bağlantı bir WebSocket’e dönüşür.
  3. Bundan sonra MQTT paketleri (CONNECT, PUBLISH, …) ikili WebSocket çerçeveleri içinde taşınır. Aktarım katmanının üstündeki her şey — QoS, retained mesajlar, Last Will, MQTT 5 özellikleri — TCP üzerindekiyle tamamen aynı şekilde çalışır.

Broker’da bir WebSocket listener’ının etkin olması gerekir. Bu listener genellikle TCP listener’ından farklı bir portta çalışır ve bazı broker’lar belirli bir path (yol) bekler.

Pratik bir sonuç: tarayıcılar JavaScript’in bir WebSocket isteğine özel header eklemesine izin vermez; bu yüzden kimlik doğrulama normalde HTTP header’ları veya çerezlerle değil, MQTT’nin kendi içinde, CONNECT paketinin kullanıcı adı ve parola alanlarıyla yapılır.

ws ve wss

ws://wss://
ŞifrelemeYok — kimlik bilgileri ve payload’lar düz metinHTTPS gibi TLS
HTTPS sayfalarından kullanılabilir miHayır (mixed content olarak engellenir)Evet
Proxy’ler ve firewall’larBazen müdahale edilir443 portunda genellikle geçer
Tipik kullanımYalnızca yerel geliştirmeDiğer her şey

wss:// tarayıcının TLS yığınını kullandığı için broker’ın sertifikasına tarayıcının güvenmesi gerekir. Kendinden imzalı (self-signed) bir sertifika JavaScript tarafında sessizce başarısız olur — gerçek sertifika hatasını görmek için https://host:port URL’sini bir kez bir sekmede açın.

Mixed content: en yaygın tarayıcı hatası

Sayfanız https:// üzerinden sunuluyorsa (neredeyse her sitede olduğu gibi) tarayıcı bir ws:// bağlantısı açma girişimlerini engeller. Konsol bir mixed content veya güvenlik hatası gösterir ve MQTT client’ı hiçbir zaman bağlanamaz. Çözüm her zaman aynıdır: broker’ın wss:// uç noktasını kullanın. Online MQTT client’ımız bu nedenle HTTPS üzerinden sunulur ve yalnızca wss:// ile bağlanır.

Portlar ve path’ler

MQTT için tek bir standart WebSocket portu yoktur; her broker kendi portunu seçer. Aşağıdakiler broker dizinimizdeki genel broker’ların uç noktalarıdır:

Brokerws://wss://Path
broker.hivemq.com80008884/mqtt
broker.emqx.io80838084/mqtt
test.mosquitto.org80808081herhangi biri
mqtt.eclipseprojects.io80443/mqtt

Yanlış bir path, genellikle MQTT daha başlamadan başarısız bir el sıkışmaya (HTTP 404 veya kapanan bir bağlantı) yol açar. Yanlış bir port ise genellikle zaman aşımına uğrar. TCP, TLS ve WebSocket portlarının tam resmi için MQTT portları yazısına bakın.

Örnek: MQTT.js ile tarayıcıda MQTT

MQTT.js en yaygın kullanılan JavaScript client’ıdır ve hem Node.js’te hem de tarayıcıda çalışır. Tarayıcıda otomatik olarak WebSocket kullanır:

browser.js
import mqtt from 'mqtt';

const client = mqtt.connect('wss://broker.emqx.io:8084/mqtt', {
  clientId: `web-${crypto.randomUUID().slice(0, 8)}`,
  // username: 'user', password: 'secret',  // for private brokers
  reconnectPeriod: 2000,
});

client.on('connect', () => {
  client.subscribe('testmqtt/ws-demo/#');
  client.publish('testmqtt/ws-demo/hello', 'hello from the browser');
});

client.on('message', (topic, payload) => {
  console.log(topic, payload.toString());
});

client.on('error', (err) => console.error('MQTT error:', err.message));

Kendi broker’ınızda WebSocket’i etkinleştirmek

Kendi broker’ınızı çalıştırıyorsanız WebSocket listener’ı genellikle birkaç satırlık yapılandırmadır. Örneğin Mosquitto’da TCP listener’ının yanına ikinci bir listener eklersiniz:

mosquitto.conf
listener 1883
protocol mqtt

listener 8080
protocol websockets

wss:// için sertifikaları doğrudan bu listener’da yapılandırabilir ya da daha yaygın olarak TLS’i 443 portundaki bir reverse proxy’de sonlandırıp düz WebSocket trafiğini broker’a iletebilirsiniz. Proxy’de WebSocket desteğinin etkin olması gerekir:

nginx location bloğu
location /mqtt {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 1h;
}

Proxy’nin read timeout değerinin MQTT keep-alive aralığınızdan uzun olduğundan emin olun; aksi halde proxy boştaki bağlantıları kapatır ve client’lar açıklanamayan bağlantı kopmaları yaşar.

Sorun giderme kontrol listesi

  • Tarayıcıdan 1883 veya 8883 portunu mu kullanıyorsunuz? Bunlar TCP portlarıdır — WebSocket listener’ına geçin.
  • Sayfa HTTPS’te, URL ws:// ile mi başlıyor? Mixed content — wss:// kullanın.
  • El sıkışma hemen mi başarısız oluyor? Path’i (/mqtt ya da hiç) ve alt protokolü kontrol edin.
  • Bir reverse proxy arkasında mısınız? Nginx ve benzeri proxy’ler Upgrade ve Connection header’larını iletmeli ve uzun ömürlü bağlantılara izin vermelidir.
  • Bağlanıyor ama atılıyor musunuz? Bu MQTT seviyesinde bir sorundur — bkz. MQTT bağlantı hataları.

Bir wss:// bağlantısını şimdi test edin

Sıkça sorulan sorular

Tarayıcım neden 1883 portunda MQTT’ye bağlanamıyor?

Tarayıcılar ham TCP soketleri açamaz ve 1883 portu TCP üzerinden düz MQTT konuşur. Bir tarayıcı client’ı bunun yerine doğru port ve path ile bir ws:// veya wss:// URL’si kullanarak broker’ın WebSocket listener’ına bağlanmalıdır.

MQTT için ws ile wss arasındaki fark nedir?

ws:// şifrelenmemiş bir WebSocket bağlantısıdır; wss:// ise TLS üzerinden WebSocket’tir. HTTPS üzerinden sunulan sayfalar yalnızca wss:// kullanabilir ve yerel testlerin ötesindeki her şey için mantıklı tek seçenek wss://’dir.

WebSocket üzerinden MQTT için hangi path’i kullanmalıyım?

Broker’a bağlıdır. EMQX ve HiveMQ dahil birçok broker /mqtt kullanır. Mosquitto ise path’ten bağımsız olarak bağlantıları kabul eder. Broker dokümantasyonunu kontrol edin; yanlış bir path genellikle WebSocket el sıkışması sırasında başarısız olur.