Łączenie się z gniazdem TCP z przeglądarki przy użyciu javascript

111

Mam aplikację vb.net, która otwiera gniazdo i nasłuchuje.

Muszę komunikować się przez to gniazdo z tą aplikacją przy użyciu javascript działającego w przeglądarce. Oznacza to, że muszę wysłać dane do tego gniazda, aby aplikacja, która nasłuchuje na tym gnieździe, mogła je pobrać, zrobić kilka rzeczy za pomocą niektórych zdalnych wywołań i uzyskać więcej danych i umieścić je z powrotem w gnieździe, którego potrzebuje mój javascript przeczytaj i wydrukuj w przeglądarce.

Próbowałem, socket.io, websockify, ale żaden nie okazał się przydatny.

Stąd pytanie, czy to, co próbuję, jest w ogóle możliwe? Czy istnieje sposób, w jaki javascript działający w przeglądarce może połączyć się z gniazdem tcp i wysłać pewne dane, a następnie nasłuchiwać w gnieździe, aby uzyskać więcej odpowiedzi na dane, a następnie wydrukować je w przeglądarce?

Jeśli to możliwe, czy ktoś może wskazać mi właściwy kierunek, który pomógłby mi w ustaleniu celu.

miecznik
źródło
3
Nie, jesteś ograniczony do WebSockets
Bergi
2
@Bergi - HTTP jest protokołem przez TCP, więc dlaczego można nawiązać połączenie HTTP, ale nie TCP?
AlikElzin-kilaka
@kilaka: Ponieważ (standardowe) interfejsy API dostępne w środowisku przeglądarki są ograniczone do tych .
Bergi
Możliwy duplikat: stackoverflow.com/questions/9154035/…
AlikElzin-kilaka
6
Widzę nowy standard wkraczający w kręgosłup Javascript: w3.org/TR/raw-sockets .
AlikElzin-kilaka

Odpowiedzi:

57

Jeśli chodzi o twój problem, obecnie będziesz musiał polegać na XHR lub websockach.

Obecnie żadna popularna przeglądarka nie zaimplementowała takiego surowego interfejsu API dla javascript, który umożliwia tworzenie i uzyskiwanie dostępu do surowych gniazd, ale przygotowywana jest wersja robocza implementacji surowego interfejsu API w JavaScript. Spójrz na te linki:
http://www.w3.org/TR/raw-sockets/
https://developer.mozilla.org/en-US/docs/Web/API/TCPSocket

Chrome obsługuje teraz surowe gniazda TCP i UDP w swoich „eksperymentalnych” interfejsach API. Te funkcje są dostępne tylko dla rozszerzeń i chociaż zostały udokumentowane, są chwilowo ukryte. Powiedziawszy to, niektórzy programiści już tworzą interesujące projekty, takie jak ten klient IRC .

Aby uzyskać dostęp do tego interfejsu API, musisz włączyć flagę eksperymentalną w manifeście swojego rozszerzenia. Korzystanie z gniazd jest dość proste, na przykład:

chrome.experimental.socket.create('tcp', '127.0.0.1', 8080, function(socketInfo) {
  chrome.experimental.socket.connect(socketInfo.socketId, function (result) {
        chrome.experimental.socket.write(socketInfo.socketId, "Hello, world!");         
    });
});
Robin Rizvi
źródło
Jakie przeglądarki obsługują surowe gniazda?
AlikElzin-kilaka
2
Jakikolwiek wzrost wydajności w porównaniu z Websockets i Rawsockets?
NiCk Newman
3
Czy zezwolenie javascript w przeglądarce na połączenie z portem TCP nie jest luką w zabezpieczeniach? Wyobraź sobie, że javascript w Twoim firefox / chrome łączy się ze wszystkim, co uruchamiasz lokalnie (np. MySQL DB) i publikujesz dane w złej witrynie?
Arun Avanathan,
@ArunAvanathan cokolwiek zrobisz z Ajaxem, możesz zrobić z gniazdami i vice-versa ... bez problemu z bezpieczeństwem, jak myślę.
Firas Abd Alrahman
1
@FirasAbdAlrahman Myślę, że istnieją różne zasady bezpieczeństwa regulujące zachowanie przeglądarki dla HTTP / S. Zatem połączenie przez gniazdo przeglądarki przez TCP to nie to samo, co HTTP / S.
Arun Avanathan
30

Będzie to możliwe za pośrednictwem interfejsu nawigatora, jak pokazano poniżej:

navigator.tcpPermission.requestPermission({remoteAddress:"127.0.0.1", remotePort:6789}).then(
  () => {
    // Permission was granted
    // Create a new TCP client socket and connect to remote host
    var mySocket = new TCPSocket("127.0.0.1", 6789);

    // Send data to server
    mySocket.writeable.write("Hello World").then(
        () => {

            // Data sent sucessfully, wait for response
            console.log("Data has been sent to server");
            mySocket.readable.getReader().read().then(
                ({ value, done }) => {
                    if (!done) {
                        // Response received, log it:
                        console.log("Data received from server:" + value);
                    }

                    // Close the TCP connection
                    mySocket.close();
                }
            );
        },
        e => console.error("Sending error: ", e)
    );
  }
);

Więcej szczegółów znajduje się w dokumentacji tcp-udp-sockets w3.org.

http://raw-sockets.sysapps.org/#interface-tcpsocket

https://www.w3.org/TR/tcp-udp-sockets/

Inną alternatywą jest użycie Chrome Sockets

Tworzenie połączeń

chrome.sockets.tcp.create({}, function(createInfo) {
  chrome.sockets.tcp.connect(createInfo.socketId,
    IP, PORT, onConnectedCallback);
});

Wysyłanie danych

chrome.sockets.tcp.send(socketId, arrayBuffer, onSentCallback);

Otrzymywanie danych

chrome.sockets.tcp.onReceive.addListener(function(info) {
  if (info.socketId != socketId)
    return;
  // info.data is an arrayBuffer.
});

Możesz również spróbować użyć HTML5 Web Sockets(Chociaż nie jest to bezpośrednia komunikacja TCP):

var connection = new WebSocket('ws://IPAddress:Port');

connection.onopen = function () {
  connection.send('Ping'); // Send the message 'Ping' to the server
};

http://www.html5rocks.com/en/tutorials/websockets/basics/

Twój serwer musi również nasłuchiwać z serwerem WebSocket, takim jak pywebsocket, alternatywnie możesz napisać własny, jak opisano w Mozilli

Darren
źródło
25
Aby bardziej rozwinąć tę odpowiedź: serwer musi również nasłuchiwać z serwerem WebSocket. WebSockets nie może połączyć się bezpośrednio z surowym gniazdem TCP. websockify to narzędzie, które działa jako proxy WebSocket-to-TCP: siedzi na serwerze i nasłuchuje połączeń WebSocket, a następnie przekazuje komunikację WebSocket do iz określonego gniazda TCP.
apsillers
58
To nie odpowiada na pytanie - websocket jest protokołem przez TCP (jak na przykład HTTP), a nie bezpośrednią komunikacją TCP.
AlikElzin-kilaka
1
ale jak umieścić wiadomość w oknie przeglądarki? :(
shzyincu
3
Ta odpowiedź jest całkowicie błędna i powinna zostać usunięta.
Brad
1
@Brad ta odpowiedź pomogła mi i pewnie pomogła innym, mając 22 głosy za.
user1378687
6

ws2sProjekt ma na celu przeniesienie gniazda do js po stronie przeglądarki. Jest to serwer sieciowy, który przekształca gniazdo sieciowe w gniazdo.

Schemat ideowy ws2s

wprowadź opis obrazu tutaj

przykładowy kod:

var socket = new WS2S("wss://ws2s.feling.io/").newSocket()

socket.onReady = () => {
  socket.connect("feling.io", 80)
  socket.send("GET / HTTP/1.1\r\nHost: feling.io\r\nConnection: close\r\n\r\n")
}

socket.onRecv = (data) => {
  console.log('onRecv', data)
}
chenyan
źródło
5

Zobacz jsocket . Sam tego nie używałem. Minęło ponad 3 lata od ostatniej aktualizacji (stan na 26.06.2014).

* Wykorzystuje flash :(

Z dokumentacji :

<script type='text/javascript'>
    // Host we are connecting to
    var host = 'localhost'; 
    // Port we are connecting on
    var port = 3000;

    var socket = new jSocket();

    // When the socket is added the to document 
    socket.onReady = function(){
            socket.connect(host, port);             
    }

    // Connection attempt finished
    socket.onConnect = function(success, msg){
            if(success){
                    // Send something to the socket
                    socket.write('Hello world');            
            }else{
                    alert('Connection to the server could not be estabilished: ' + msg);            
            }       
    }
    socket.onData = function(data){
            alert('Received from socket: '+data);   
    }

    // Setup our socket in the div with the id="socket"
    socket.setup('mySocket');       
</script>
AlikElzin-kilaka
źródło
0

Rozwiązaniem, którego naprawdę szukasz, są gniazda sieciowe. Jednak w ramach projektu chromium opracowano kilka nowych technologii, które są bezpośrednimi połączeniami TCP chromu TCP

Sdedelbrock
źródło
0

Aby osiągnąć to, co chcesz, musiałbyś napisać dwie aplikacje (na przykład w Javie lub Pythonie):

  1. Aplikacja Bridge, która znajduje się na komputerze klienta i może obsługiwać zarówno gniazda TCP / IP, jak i WebSockets. Będzie współpracować z danym gniazdem TCP / IP.

  2. Aplikacja po stronie serwera (taka jak JSP / Servlet WAR), która może komunikować się z WebSockets. Zawiera przynajmniej jedną stronę HTML (w razie potrzeby z kodem przetwarzania po stronie serwera), do której przeglądarka ma dostęp.

To powinno tak działać

  1. Mostek otworzy połączenie WS z aplikacją internetową (ponieważ serwer nie może połączyć się z klientem).
  2. Aplikacja internetowa poprosi klienta o identyfikację
  3. Klient mostu wysyła pewne informacje o identyfikatorze do serwera, który przechowuje je w celu identyfikacji mostu.
    1. Strona widoczna w przeglądarce łączy się z serwerem WS za pomocą JS.
    2. Powtórz krok 3, ale dla strony opartej na JS
    3. Strona oparta na JS wysyła polecenie do serwera, w tym do którego mostu ma przejść.
    4. Serwer przekazuje polecenie do mostka.
    5. Most otwiera gniazdo TCP / IP i współdziała z nim (wysyła wiadomość, otrzymuje odpowiedź).
    6. Most wysyła odpowiedź do serwera za pośrednictwem WS
    7. WS przekazuje odpowiedź do strony widocznej w przeglądarce
    8. JS przetwarza odpowiedź i odpowiednio reaguje
    9. Powtarzaj tę czynność do momentu rozłączenia / zwolnienia dowolnego klienta

Uwaga 1: Powyższe kroki są ogromnym uproszczeniem i nie zawierają informacji o obsłudze błędów i żądaniach keepAlive w przypadku, gdy klient rozłączy się przedwcześnie lub serwer musi poinformować klientów, że zamyka / restartuje.

Uwaga 2: W zależności od potrzeb może być możliwe scalenie tych składników w jeden, jeśli dany serwer gniazd TCP / IP (z którym komunikuje się most) znajduje się na tym samym komputerze, co aplikacja serwera.

Agi Hammerthief
źródło