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?
- Client bir HTTP(S) bağlantısı açar ve
wss://broker.emqx.io:8084/mqttgibi bir URL’ye,mqttalt protokolünü (subprotocol) talep eden bir WebSocket upgrade isteği gönderir. - Broker
101 Switching Protocolsile yanıt verir ve bağlantı bir WebSocket’e dönüşür. - 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:// | |
|---|---|---|
| Şifreleme | Yok — kimlik bilgileri ve payload’lar düz metin | HTTPS gibi TLS |
| HTTPS sayfalarından kullanılabilir mi | Hayır (mixed content olarak engellenir) | Evet |
| Proxy’ler ve firewall’lar | Bazen müdahale edilir | 443 portunda genellikle geçer |
| Tipik kullanım | Yalnızca yerel geliştirme | Diğ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:
| Broker | ws:// | wss:// | Path |
|---|---|---|---|
| broker.hivemq.com | 8000 | 8884 | /mqtt |
| broker.emqx.io | 8083 | 8084 | /mqtt |
| test.mosquitto.org | 8080 | 8081 | herhangi biri |
| mqtt.eclipseprojects.io | 80 | 443 | /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:
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:
listener 1883
protocol mqtt
listener 8080
protocol websocketswss:// 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:
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 (
/mqttya da hiç) ve alt protokolü kontrol edin. - Bir reverse proxy arkasında mısınız? Nginx ve benzeri proxy’ler
UpgradeveConnectionheader’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.