• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

WebSocket - brak połączenia

Object Storage Arubacloud
0 głosów
553 wizyt
pytanie zadane 7 czerwca 2021 w JavaScript przez rafaeru Początkujący (330 p.)

Witam, mam problem z uzyskaniem połączenia WebSocket poprzez przeglądarkę. 

JS:

const socket = new WebSocket('ws://localhost:1234');
 
socket.onopen = function(evt) {
	alert('Connected.');
};
 
socket.onclose = function(evt) {
	alert('Disconnected.');
};
 
socket.onmessage = function(evt) {
	alert(evt.value);
};
 
socket.onerror = function(evt) {
	alert('Error.');
};
 
function send() {
	var txt = document.getElementyById('txt');
	var val = txt.value;
	socket.send(val);
};

HTML:

<!doctype html>
<html lang="pl">
	<head>
		<meta charset="utf-8"/>
		<title>Client</title>
		<script src="websocket.js"></script>
	</head>
	<body>
		Message:<input type="text" id="txt"/>
		<button onClick="send();">Send</button>
	</body>
</html>

Jakie warunki muszę dokładnie spełnić aby nawiązać to połącznie ? Potrzebuje jakiegoś serwera WebSocket ?

Czytałem, że Chrome blokuje połączenia po localhost bez certyfikatu SSL.

Czy może być to spowodowane dostawcą mojego internetu ?

1 odpowiedź

+1 głos
odpowiedź 7 czerwca 2021 przez tangarr Mędrzec (154,780 p.)
wybrane 9 czerwca 2021 przez rafaeru
 
Najlepsza
Żeby nawiązać połączenie ws://localhost:1234 musisz mieć uruchomiony (na urządzeniu z którego nawiązujesz połączenie) jakiś program nasłuchujący WebSocket na porcie 1234
komentarz 7 czerwca 2021 przez rafaeru Początkujący (330 p.)
Czyli jeśli mam uruchomiony program a dalej ten błąd to znaczy, że program nie nasłuchuje?
komentarz 7 czerwca 2021 przez tangarr Mędrzec (154,780 p.)
Najpierw sprawdź netstatem czy masz otwarty port 1234.
komentarz 7 czerwca 2021 przez rafaeru Początkujący (330 p.)

echoserver to aplikacja nasłuchująca i niby jest ale z IPv6

komentarz 7 czerwca 2021 przez Comandeer Guru (600,810 p.)
A echoserver obsługuje protokół WebSockets? Bo to wygląda jak socket TCP, co jest zupełnie inną rzeczą.
1
komentarz 7 czerwca 2021 przez tangarr Mędrzec (154,780 p.)
Przydałby się kod tego serwera.
komentarz 7 czerwca 2021 przez rafaeru Początkujący (330 p.)

@Comandeer, tak obsługuje.

Aplikacja tworzona w Qt, poniżej daje kod źródłowy:
https://github.com/rafaeru97/webserver

komentarz 7 czerwca 2021 przez JakSky Stary wyjadacz (14,770 p.)

@Comandeer, przecież WebSocket działa na TCP....

 

komentarz 7 czerwca 2021 przez Comandeer Guru (600,810 p.)
Tak, tak samo jak starsze wersje HTTP. Ale TCP nie oznacza automatycznie obsługi protokołu HTTP czy WebSockets.
komentarz 7 czerwca 2021 przez tangarr Mędrzec (154,780 p.)
edycja 7 czerwca 2021 przez tangarr

Jesteś pewien, że podałeś link do prawidłowego kodu? Ten program tylko nasłuchuje i wyświetla w oknie dialogowym wiadomości które otrzymał. Nazwa echo server sugeruje że program będzie odpowiadał do klienta taką samą wiadomością.

Ponadto przedstawiony kod tworzy gniazdo używające protokołu IPv4 a twój program nasłuchuje na IPv6 (nie wykluczam, że to może być błąd w Qt)

Edit: Może dodaj w js obsługę eventu onerror i wyświetl cały event. Może tam znajdziesz więcej informacji. Ewentualnie zamiast localhosta użyj adresu ::1

komentarz 7 czerwca 2021 przez rafaeru Początkujący (330 p.)

Używając adresu ::1 też nic nie dostaje a błąd onerror jest undefined

Kod ma właśnie działać tak jak napisałeś bo chce na początku otrzymać połączenie aby zacząć działać dalej. Jeśli masz jakąś sprawdzoną bibliotekę obsługującą WebSockety inną niż Qt w C++ to chętnie się dowiem, męczę się z tym już trochę czasu.

1
komentarz 7 czerwca 2021 przez tangarr Mędrzec (154,780 p.)

Zamiast alertów wypisuj wiadomości na konsolę.

socket.onerror = function(evt) {
    console.warn(evt);
};

Uruchomiłem ten kod u siebie i połączenie do websocketa działa.

Zastanawiam się, czy przypadkiem nie masz uruchomionego innego programu używającego tego portu.
Zmodyfikuj kod serwera tak, aby informował o błędzie gdy nie uda mu się zbindować portu.

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    mWebServer = new WebServer(this);
    if (!mWebServer->listen(QHostAddress::LocalHost, 1234)) {
        QMessageBox::critical(this, "Error", "QWebServer::listen() failed: "+mWebServer->errorString());
        QApplication::exit(1);
    }
    connect(mWebServer, SIGNAL(reciveMessage(QString)), this, SLOT(reciveMessage(QString)));
}

 

komentarz 7 czerwca 2021 przez rafaeru Początkujący (330 p.)
edycja 7 czerwca 2021 przez rafaeru

Tak, masz racje jest już używany.

Zmieniłem port na 4321 ale nadal aplikacja nie otrzymuje tego co wysyłam przez JavaScript ale wygląda na to, że nasłuchuje dobrze bo gdy zamknę aplikacje automatycznie tracę połączenie z JavaScript. Może coś spaprałem w kodzie aplikacji?

Tutaj screen z portu 4321, wygląda git:

W konsoli JS czysto.

1
komentarz 8 czerwca 2021 przez tangarr Mędrzec (154,780 p.)

Sprawdź logi aplikacji. Widziałem, że któreś połączenie sygnał-slot było nieprawidłowe.

connect(mSocket, SIGNAL(textMessageRecived(QString)), this, SLOT(onReciveMessage(QString)));
// literówka, powinno być
//connect(mSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(onReciveMessage(QString)));

Szczerze to polecam używanie nowej składni połączeń

connect(mSocket, &QWebSocket::textMessageReceived, this, &WebServer::onReciveMessage);

Nowe połączenia tworzone są w trakcie kompilacji, nie ma możliwości skompilowania kodu z literówką w nazwie sygnału lub slotu.

komentarz 8 czerwca 2021 przez rafaeru Początkujący (330 p.)
edycja 8 czerwca 2021 przez rafaeru

Jeśli dobrze rozumiem to linijka w webserver.cpp

connect(mSocket, &QWebSocket::textMessageReceived, this, &WebServer::onReciveMessage);

Odpowiada za pobranie tekstu wiadomości przy nowym połączeniu ?

W sensie jest odpowiednikiem JS'owego ?

socket.onmessage = function(evt) {
	alert(evt.value);
};

Czemu wcześniej miałem też podobną linijkę w pliku dialog.cpp (za co ona jest odpowiedzialna)?

connect(mWebServer, SIGNAL(reciveMessage(QString)), this, SLOT(reciveMessage(QString)));

Bo nie do końca to rozumiem, ale działa.

komentarz 8 czerwca 2021 przez tangarr Mędrzec (154,780 p.)

Mechanizm sygnałów i slotów służy do "przesyłania" wiadomości/danych/zdarzeń między obiektami. Sygnały są funkcjami rozgłaszającymi, informują o wystąpieniu zdarzenia. Sloty są funkcjami reagującymi na zdarzenie.
Funkcja QObject::connect służy do parowania sygnałów ze slotami.
Twoje połączenie było nieprawidłowe z powodu literówki w nazwie sygnału. Sygnał emitowany przez QWebSocket emitowany w momencie otrzymania wiadomości nazywa się textMessageReceived a ty (prawdopodobnie z powodu nieznajomości angielskiego słowa receive) pominąłeś literkę e smiley

PS. Sygnały w Qt bardziej przypominają JSowy addEventListener. Do jednego sygnału można podłączyć wiele slotów.

komentarz 8 czerwca 2021 przez rafaeru Początkujący (330 p.)

Dzięki, muszę jeszcze o tym poczytać. Czyli analogiczne mogę dodać wysyłanie jakiejś wiadomości z aplikacji Qt do JS. Bazując na: https://doc.qt.io/qt-5/qwebsocket.html

Powinienem użyć funkcji

sendTextMessage(const QString &message)

i tutaj nie będzie żadnego sygnału bo to ja ją wywołuje?

Drugie pytanie to docelowo chcę stworzyć program który będzie przesyłał mi 2 zmienne, lepiej będzie użyć 2 portów aby osobno przesłać obie zmienne czy np. da się wysłać tablicę(na pierwszą myśl przyszło mi, żeby przesyłać te wartości np. po przecinku i sobie potem je oddzielać bo to string)? Masz może doświadczenie i wiesz jak będzie bardziej profesjonalnie?

1
komentarz 8 czerwca 2021 przez tangarr Mędrzec (154,780 p.)
Masz dwa rozwiązania:
1. Wysłać dane w postaci binarnej - wymaga mniej danych ale sam musisz zapewnić odpowiednie kodowanie i odkodowywanie wiadomości po obu stronach
2. Wysłać dane w postaci tekstowej - ta metoda jest bardzo elastyczna i nie musisz się przejmować prawidłową obsługą różnych architektur procesorowych. Możliwe sposoby na przesył danych:
- wiadomość zawiera dane oddzielone jakimś wybranym symbolem np # lub |
- wiadomość w formacie XML
- wiadomość w formacie JSON (ten format powstał specjalnie dla stron internetowych) https://doc.qt.io/qt-5/json.html

Podobne pytania

0 głosów
1 odpowiedź 40 wizyt
+1 głos
1 odpowiedź 254 wizyt
pytanie zadane 30 października 2022 w JavaScript przez JaaO Początkujący (490 p.)
0 głosów
0 odpowiedzi 126 wizyt
pytanie zadane 27 sierpnia 2020 w JavaScript przez Massacra Nowicjusz (120 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...