2012-12-09 11 views
11

Próbuję włączyć komunikację tcp, http i websocket.io na tym samym porcie. Zacząłem od serwera tcp (część powyżej //// linia), działało. Następnie uruchomiłem echo server example found on websocket.io (część poniżej //// linia), również zadziałało. Ale kiedy próbuję je scalić, tcp już nie działa.Czy można włączyć tcp, http i websocket przy użyciu tego samego portu?

SO, czy można włączyć tcp, http i websockets przy użyciu tego samego portu? Czy muszę słuchać na innym porcie dla połączeń TCP?

var net = require('net'); 
var http = require('http'); 
var wsio = require('websocket.io'); 

var conn = []; 

var server = net.createServer(function(client) {//'connection' listener 
    var info = { 
     remote : client.remoteAddress + ':' + client.remotePort 
    }; 
    var i = conn.push(info) - 1; 
    console.log('[conn] ' + conn[i].remote); 

    client.on('end', function() { 
     console.log('[disc] ' + conn[i].remote); 
    }); 

    client.on('data', function(msg) { 
     console.log('[data] ' + conn[i].remote + ' ' + msg.toString()); 
    }); 

    client.write('hello\r\n'); 
}); 

server.listen(8080); 

/////////////////////////////////////////////////////////// 

var hs = http.createServer(function(req, res) { 
    res.writeHead(200, { 
     'Content-Type' : 'text/html' 
    }); 
    res.end(['<script>', "var ws = new WebSocket('ws://127.0.0.1:8080');", 'ws.onmessage = function (data) { ws.send(data); };', '</script>'].join('')); 
}); 

hs.listen(server); 

var ws = wsio.attach(hs); 
var i = 0, last; 

ws.on('connection', function(client) { 

    var id = ++i, last 

    console.log('Client %d connected', id); 

    function ping() { 
     client.send('ping!'); 
     if (last) 
      console.log('Latency for client %d: %d ', id, Date.now() - last); 
     last = Date.now(); 
    }; 

    ping(); 
    client.on('message', ping); 

}); 
+1

HTTP zazwyczaj biegnie na szczycie TCP. Co rozumiesz przez HTTP i TCP? –

+0

Dlatego mam wątpliwości. Mój serwer musi komunikować się z internetowymi gniazdami poprzez przeglądarki i połączenia TCP za pośrednictwem aplikacji mobilnych. Potrzebuję więc obu protokołów. –

+0

Być może możesz nasłuchiwać jako surowego TCP, a jeśli wykryjesz HTTP, przekaż do drugiego programu obsługi ręcznie. Podobnie, jeśli wykryjesz WS z serwera HTTP (WS uruchamia się jako HTTP), deleguj ponownie. –

Odpowiedz

22

Można mieć wiele różnych protokołów obsługiwane przez tego samego portu, ale istnieją pewne zastrzeżenia:

  • musi być jakiś sposób na serwer w celu wykrycia (lub negocjować) protokół, który klient chce rozmawiać . Możesz myśleć o oddzielnych portach jako o normalnym sposobie wykrywania protokołu, o którym klient chce mówić.

  • Tylko jeden proces serwera może faktycznie nasłuchiwać na porcie. Ten serwer może służyć tylko do wykrywania typu protokołu, a następnie do przekazywania wielu innych serwerów, ale każdy port jest własnością procesu pojedynczego serwera.

  • Nie można obsługiwać wielu protokołów, w których serwer mówi pierwszy (ponieważ nie ma sposobu na wykrycie protokołu klienta). Możesz obsługiwać protokół z pojedynczym serwerem z wieloma protokołami klienta-pierwszego (dodając krótkie opóźnienie po zaakceptowaniu, aby zobaczyć, czy klient wyśle ​​dane), ale jest to trochę nieudane.

Wyraźne celem projektu protokołu websocket było umożliwienie websocket protokoły HTTP i dzielić ten sam port serwera. Początkowy handshake WebSocket to żądanie aktualizacji zgodne z protokołem HTTP.

Serwer/most jest przykładem serwera, który może wypowiadać 5 różnych protokołów na tym samym porcie: HTTP, HTTPS (szyfrowany HTTP), WS (WebSockets), WSS (szyfrowane WebSockets) i odpowiedź polityczna Flash. Serwer osiąga szczyt przy pierwszym znaku przychodzącego żądania, aby ustalić, czy jest zaszyfrowany TLS (HTTPS lub WSS), czy też zaczyna się od "<" (żądanie polityki Flash). Jeśli jest to żądanie polityki Flash, to odczytuje żądanie, odpowiada i zamyka połączenie. W przeciwnym razie odczytuje uzgadnianie HTTP (zaszyfrowane lub nie), a nagłówki połączenia i uaktualnienia określają, czy jest to żądanie WebSocket, czy zwykłe żądanie HTTP.

Zastrzeżenie: Zrobiłem websockify

+0

@kanaka: ilu klientów może połączyć się z jednym portem? Chciałbym wiedzieć, że w czasie, ile połączeń z gniazdami internetowymi może obsługiwać aplikacja internetowa Java? Na każdym żądaniu gniazda sieciowego od klienta potrzebujemy portu diff na serwerze? –

+1

@DaxJoshi to prawdopodobnie lepiej jako osobne pytanie. Tak naprawdę nie trzeba nic robić z Websockets. Port serwera, na którym są akceptowane połączenia TCP, może obsługiwać wiele połączeń. Nie masz oddzielnego portu serwera dla każdego klienta. W przypadku websockify, jeśli chcesz, aby różni klienci łączyli się z różnymi celami za pośrednictwem websockify, powinieneś spojrzeć na [TokenFile plugin/target config] (https://github.com/kanaka/websockify/wiki/Token-based -target-selection) funkcjonalność websockify. – kanaka

1

Krótka odpowiedź - NIE, nie można mieć różnych serwerów TCP/HTTP/Websocket działających na tym samym porcie.

Longish answer - Zarówno websockets, jak i HTTP działają na TCP. Możesz więc myśleć o serwerze http lub serwerze websocket jako niestandardowym serwerze TCP (z pewnym stanem kodowania/dekodowania MGMT i protokołu). Nie jest możliwe, aby wiele gniazd łączyło się z tą samą parą portów/protokołów na komputerze, więc pierwsza z nich wygra, a następne otrzymają wyjątki związane z oprawami.

Powiązane problemy