Вэб Сокеты и DNS

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Тема прошла совсем мимо меня, пытаюсь прояснить, из описания протокола вижу, что переход на Сокеты инициируется после соединения по http. Но нахожу такие ссылки: ws://176.116.208.112:8073/ws/
Это надо прописывать в DNS я так понимаю?

rkit
Offline
Зарегистрирован: 23.11.2016

Что "это"? DNS это система пробразования "site.com" в "176.116.208.112"

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

Что "это"? DNS это система пробразования "site.com" в "176.116.208.112"

так я и спрашиваю ws прописывается или нет, запись типа A?

rkit
Offline
Зарегистрирован: 23.11.2016

rkit пишет:

DNS это система пробразования "site.com" в "176.116.208.112"

Попробуй еще раз прочитать и объяснить мне, где тут "ws"

negavoid2
Offline
Зарегистрирован: 06.05.2020

Если очень хочется, то можно прописать site.com A 176.116.208.112 и далее обращаться к ws://site.com:8073/ws/

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

negavoid2 пишет:

Если очень хочется, то можно прописать site.com A 176.116.208.112 и далее обращаться к ws://site.com:8073/ws/

Это сторонний ресурс, открывается по http и потом переходит на ws, по прямой ссылке ws:// ... не открывается, задумался, почему? ...пытаюсь понять...с сокетами дел не имел, совсем...

negavoid2
Offline
Зарегистрирован: 06.05.2020

Например, потому что им так захотелось :) Или, например, потому что сервер вебсокетов не на том же домене, что и http(s). Или вообще в облаке, их, например много, и они без доменов.

А что вы хотели открыть по прямой ссылке ws:// ? Открывайте телнет, туда open ip:port и дальше туда впишите GET /ws/, всякие там upgrade-protocol: websocket и он вероятно ответит.

rkit
Offline
Зарегистрирован: 23.11.2016

ua6em пишет:

 по прямой ссылке ws:// ... не открывается, задумался, почему?

И каким образом ты пытаешься "открыть"?

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

Это сторонний ресурс, открывается по http и потом переходит на ws, по прямой ссылке ws:// ... не открывается, задумался, почему? ...пытаюсь понять...с сокетами дел не имел, совсем...

все равно осталось непонятно, зачем это прописывать ТЕБЕ, если ресурс сторонний?

Как пример - разве для того, чтобы открыть гугль по IP - ты прописываешь что-то в _своем_ DNS ? прописывать или не прописывать это в ДНСе - дело хозяина ресурса, а не клиентов

negavoid2
Offline
Зарегистрирован: 06.05.2020

Потому что дедушка радиолюбитель, а не погромист :)

А вообще, можно и прописать в свой днс, например домен h*i, а ипак гугла, и всё будет прекрасно открываться.

b707
Offline
Зарегистрирован: 26.05.2017

negavoid2 пишет:

А вообще, можно и прописать в свой днс, например домен h*i, а ипак гугла, и всё будет прекрасно открываться.

можно, конечно, и извратиться... прописать записи для чужой зоны в свой ДНС :) Только в разы проще и быстрее это делается алиасами в файле hosts и подобных

negavoid2
Offline
Зарегистрирован: 06.05.2020

Особенно на айфоне.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

ua6em пишет:

 по прямой ссылке ws:// ... не открывается, задумался, почему?

И каким образом ты пытаешься "открыть"?

браузер обновлен, вэбсокеты поддерживает, им и открыть пытаюсь, НЕ?

rkit
Offline
Зарегистрирован: 23.11.2016

А конкретнее? В адресную строку вводишь, что ли?

negavoid2
Offline
Зарегистрирован: 06.05.2020
let ws = new WebSocket("ws://site.com:1234/ws/");

ws.onmessage = function(e) {
  console.log('${e.data}');
};

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

А конкретнее? В адресную строку вводишь, что ли?

а куда, кроме адресной строки там можно ввести

negavoid2
Offline
Зарегистрирован: 06.05.2020

Не вижу смысла продолжать тему :)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

negavoid2 пишет:

Потому что дедушка радиолюбитель, а не погромист :)

вот это точно, вдобавок ни разу )))

sadman41
Offline
Зарегистрирован: 19.10.2016

To guarantee uniformity, all URIs follow a predefined set of syntax rules,[1] but also maintain extensibility through a separately defined hierarchical naming scheme (e.g. http://).
https://en.m.wikipedia.org/wiki/Uniform_Resource_Identifier

https://en.m.wikipedia.org/wiki/List_of_URI_schemes

Браузер не обязан поддерживать обработку всех существующих схем ресурсов. И он не знает, что делать с ресурсом ws - отрисовывать, музыку играть, совать туда куки или что-то ещё.

А вот JavaScript engine, которую запускает браузер, уже знает, как обрабатывать эту схему и имеет набор методов для доступа к ней.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:
To guarantee uniformity, all URIs follow a predefined set of syntax rules,[1] but also maintain extensibility through a separately defined hierarchical naming scheme (e.g. http://). https://en.m.wikipedia.org/wiki/Uniform_Resource_Identifier https://en.m.wikipedia.org/wiki/List_of_URI_schemes Браузер не обязан поддерживать обработку всех существующих схем ресурсов. И он не знает, что делать с ресурсом ws - отрисовывать, музыку играть, совать туда куки или что-то ещё. А вот JavaScript engine, которую запускает браузер, уже знает, как обрабатывать эту схему и имеет набор методов для доступа к ней.

я подозревал это, благодарю

Logik
Offline
Зарегистрирован: 05.08.2014

Та не пугайся, вв JS все просто. Вот пример html с WS. Управление светофором типа.

const char* PROGMEM webs="<html><head><meta charset='utf-8'></head><h1>Svetofor</h1> \
<table><tr><td><input type='button' onclick='OpenWS()' value='Open'/> \
</td><td><input type='button' onclick='CloseWS()'value='Close'/> \
</tr><tr> \
</td><td><input type='button' onclick='snd(0x11)' value=\"UpRed\"/> \
</td><td><input type='button' onclick='snd(0x22)' value=\"UpGreen\"/> \
</td><td><input type='button' onclick='snd(0x33)' value=\"UpYellow\"/> \
</td><td><input type='button' onclick='snd(0x44)' value=\"Red\"/> \
</td><td><input type='button' onclick='snd(0x88)' value=\"Green\"/> \
</td><td><input type='button' onclick='snd(0xcc)' value=\"Yellow\"/> \
</td><td><input type='button' onclick='snd(0x04)' value=\"Red blink\"/> \
</td><td><input type='button' onclick='snd(0x84)' value=\"Red\\Green blink\"/> \
</td><td><input type='button' onclick='snd(0x5b)' value=\"разный\"/> \
</td><td><input type='button' onclick='snd(0xaa)' value=\"совсем зеленый\"/> \
</td></tr></table>\
<script language='Javascript'> \
ESP_URL = 'ws://192.168.0.21:5000'; \
var socketW=null;\
function RecWS(messageEvent){}\
function snd(d){if(socketW!=null)socketW.send(d);}\
function OpenWS(){if(socketW==null) socketW= new WebSocket(ESP_URL);if(socketW!=null){socketW.onmessage=RecWS;} \
}\
function OnClose(Event){socketW=null;}\
</script></html>";

Нажал на кнопку snd вызвался байт отправился на ардуину. Когда с ардуины данные прийдут, вызовется RcvWS с данными в параметре, парсиш и в html суеш. Почитай немного про DOM. Про DNS не читай )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Зачем это я понял, осталось найти задачу где применить...

rkit
Offline
Зарегистрирован: 23.11.2016

Любая панель, отображающая данные в реальном времени. Или управление роботами.

Logik
Offline
Зарегистрирован: 05.08.2014

Ага. Везде где ардуине нужен экран и/или кнопки можно тулить вебинтерфейс. Даже заместо светодиода на 13й ноге.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Пришли ESP32, пытаюсь изучать, что в ней не так?
 

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
E (32) SPIFFS: mount failed, -10025
Error mounting SPIFFS


 

rkit
Offline
Зарегистрирован: 23.11.2016

SPIFFS еще нужно отдельно залить. Не знаю, как это делается в IDE.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

SPIFFS еще нужно отдельно залить. Не знаю, как это делается в IDE.

Благодарю, также через меню IDE, нажатием кнопки boot на ESP32

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Не могу понять!

Подключаюсь к серверу двумя смартфонами, при нажатии кнопки на любом из смартфонов вижу в мониторе порта смену режима, надеялся, что и индикатор светодиода на смартфонах будет отрабатывать синхронно, ан нет, кривой код?
Изучаю пример по этому материалу.

SSID и защищенный режим точки тоже не устанавливается...
 

Код:
 

#include <WiFi.h>
#include <SPIFFS.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>

// Constants
const char* ssid = "ESP32AP";
const char* password =  "12345678";
const char* msg_toggle_led = "toggleLED";
const char* msg_get_led = "getLEDState";
const int dns_port = 53;
const int http_port = 80;
const int ws_port = 1337;
const int led_pin = 13;

// Globals
AsyncWebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(1337);
char msg_buf[10];
int led_state = 0;

/***********************************************************
 * Functions
 */

// Callback: receiving any WebSocket message
void onWebSocketEvent(uint8_t client_num,
                      WStype_t type,
                      uint8_t * payload,
                      size_t length) {

  // Figure out the type of WebSocket event
  switch(type) {

    // Client has disconnected
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\n", client_num);
      break;

    // New client has connected
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(client_num);
        Serial.printf("[%u] Connection from ", client_num);
        Serial.println(ip.toString());
      }
      break;

    // Handle text messages from client
    case WStype_TEXT:

      // Print out raw message
      Serial.printf("[%u] Received text: %s\n", client_num, payload);

      // Toggle LED
      if ( strcmp((char *)payload, "toggleLED") == 0 ) {
        led_state = led_state ? 0 : 1;
        Serial.printf("Toggling LED to %u\n", led_state);
        digitalWrite(led_pin, led_state);

      // Report the state of the LED
      } else if ( strcmp((char *)payload, "getLEDState") == 0 ) {
        sprintf(msg_buf, "%d", led_state);
        Serial.printf("Sending to [%u]: %s\n", client_num, msg_buf);
        webSocket.sendTXT(client_num, msg_buf);

      // Message not recognized
      } else {
        Serial.println("[%u] Message not recognized");
      }
      break;

    // For everything else: do nothing
    case WStype_BIN:
    case WStype_ERROR:
    case WStype_FRAGMENT_TEXT_START:
    case WStype_FRAGMENT_BIN_START:
    case WStype_FRAGMENT:
    case WStype_FRAGMENT_FIN:
    default:
      break;
  }
}

// Callback: send homepage
void onIndexRequest(AsyncWebServerRequest *request) {
  IPAddress remote_ip = request->client()->remoteIP();
  Serial.println("[" + remote_ip.toString() +
                  "] HTTP GET request of " + request->url());
  request->send(SPIFFS, "/index.html", "text/html");
}

// Callback: send style sheet
void onCSSRequest(AsyncWebServerRequest *request) {
  IPAddress remote_ip = request->client()->remoteIP();
  Serial.println("[" + remote_ip.toString() +
                  "] HTTP GET request of " + request->url());
  request->send(SPIFFS, "/style.css", "text/css");
}

// Callback: send 404 if requested file does not exist
void onPageNotFound(AsyncWebServerRequest *request) {
  IPAddress remote_ip = request->client()->remoteIP();
  Serial.println("[" + remote_ip.toString() +
                  "] HTTP GET request of " + request->url());
  request->send(404, "text/plain", "Not found");
}

/***********************************************************
 * Main
 */

void setup() {
  // Init LED and turn off
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, LOW);

  // Start Serial port
  Serial.begin(115200);

  // Make sure we can read the file system
  if( !SPIFFS.begin()){
    Serial.println("Error mounting SPIFFS");
    while(1);
  }

  // Start access point
  WiFi.softAP(ssid, password);

  // Print our IP address
  Serial.println();
  Serial.println("AP running");
  Serial.print("My IP address: ");
  Serial.println(WiFi.softAPIP());

  // On HTTP request for root, provide index.html file
  server.on("/", HTTP_GET, onIndexRequest);

  // On HTTP request for style sheet, provide style.css
  server.on("/style.css", HTTP_GET, onCSSRequest);

  // Handle requests for pages that do not exist
  server.onNotFound(onPageNotFound);

  // Start web server
  server.begin();

  // Start WebSocket server and assign callback
  webSocket.begin();
  webSocket.onEvent(onWebSocketEvent);
  
}

void loop() {
  
  // Look for and handle WebSocket data
  webSocket.loop();
}

 

Код странички:
 

<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>

<script language="javascript" type="text/javascript">

var url = "ws://192.168.4.1:1337/";
var output;
var button;
var canvas;
var context;

// This is called when the page finishes loading
function init() {

    // Assign page elements to variables
    button = document.getElementById("toggleButton");
    output = document.getElementById("output");
    canvas = document.getElementById("led");
    
    // Draw circle in canvas
    context = canvas.getContext("2d");
    context.arc(25, 25, 15, 0, Math.PI * 2, false);
    context.lineWidth = 3;
    context.strokeStyle = "black";
    context.stroke();
    context.fillStyle = "black";
    context.fill();
    
    // Connect to WebSocket server
    wsConnect(url);
}

// Call this to connect to the WebSocket server
function wsConnect(url) {
    
    // Connect to WebSocket server
    websocket = new WebSocket(url);
    
    // Assign callbacks
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
}

// Called when a WebSocket connection is established with the server
function onOpen(evt) {

    // Log connection state
    console.log("Connected");
    
    // Enable button
    button.disabled = false;
    
    // Get the current state of the LED
    doSend("getLEDState");
}

// Called when the WebSocket connection is closed
function onClose(evt) {

    // Log disconnection state
    console.log("Disconnected");
    
    // Disable button
    button.disabled = true;
    
    // Try to reconnect after a few seconds
    setTimeout(function() { wsConnect(url) }, 2000);
}

// Called when a message is received from the server
function onMessage(evt) {

    // Print out our received message
    console.log("Received: " + evt.data);
    
    // Update circle graphic with LED state
    switch(evt.data) {
        case "0":
            console.log("LED is off");
            context.fillStyle = "black";
            context.fill();
            break;
        case "1":
            console.log("LED is on");
            context.fillStyle = "red";
            context.fill();
            break;
        default:
            break;
    }
}

// Called when a WebSocket error occurs
function onError(evt) {
    console.log("ERROR: " + evt.data);
}

// Sends a message to the server (and prints it to the console)
function doSend(message) {
    console.log("Sending: " + message);
    websocket.send(message);
}

// Called whenever the HTML button is pressed
function onPress() {
    doSend("toggleLED");
    doSend("getLEDState");
}

// Call the init function as soon as the page loads
window.addEventListener("load", init, false);

</script>

<h2>LED Control</h2>

<table>
    <tr>
        <td><button id="toggleButton" onclick="onPress()" disabled>Toggle LED</button></td>
        <td><canvas id="led" width="50" height="50"></canvas></td>
    </tr>
</table>

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016