Webserver works on LAN, does not work on external IP
Posted: Sat Mar 03, 2018 2:30 pm
Hi,
Spent a lot of time to see temperature sensor data from Webserver, also to control my boiler via Relay.
Strange bug: server works perfectly from PC internally or from external IP. But with mobile phones works internally, but from external IP hangs up and does not load the page...
Please help to understand where is the problem. Here is the code:
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <Hash.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
//temp libraries
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS D2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
static const char ssid[] = "ssid";
static const char password[] = "password";
MDNSResponder mdns;
static void writeLED(bool);
ESP8266WiFiMulti WiFiMulti;
ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<!DOCTYPE html><html><head><style>@import url(https://fonts.googleapis.com/css?family ... 00,500,600);
#element1 { width:200px; height:200px; border-radius:25%; display:inline-block;
background: green; background:-webkit-linear-gradient(red, blue); background:-o-linear-gradient(red, blue);
background: -moz-linear-gradient(red, blue);background: linear-gradient(red, blue); }
#element2 { width:160px; height:160px; border-radius:20%; display:inline-block; background:#e3e3e4; margin-top:20px; }
#tekstas { position:relative; left:-10px; top: 5px; }
.txt { text-align:center; font-family:'Dosis'; color:maroon; }
.txt strong { font-size:115px; }
.txt span { position:absolute; font-size:30px; left:135px; top:45px; }
</style>
<script>
var websock;
function start() {
websock = new WebSocket('ws://' + window.location.hostname + ':81/');
websock.onopen = function(evt) { console.log('websock open'); }
websock.onclose = function(evt) { console.log('websock close'); }
websock.onerror = function(evt) { console.log(evt); }
websock.onmessage = function(evt) {
console.log(evt);
var e = document.getElementById('ledstatus');
var t1 = document.getElementById('temp1');
var t2 = document.getElementById('temp2');
if (evt.data.includes('ledon')) {
e.style.color = 'red';
e.textContent = 'ON';
}
else if (evt.data.includes('ledoff')) {
e.style.color = 'black';
e.textContent = 'OFF';
}
else {
console.log('unknown event');
}
if (evt.data.length > 6) {
t1.textContent = evt.data.substring(6,8);
t2.textContent = evt.data.substring(8);
}
}
}
function buttonclick(e) {
websock.send(e.id);
}
</script>
</head>
<body class="txt" onload="javascript:start();">
<h1>Namai, Ateities 77</h1>
<div><div id="element1"><div id="element2"><div id="tekstas">
<strong id="temp1"></strong>
<span id="temp2"></span>
</div></div></div></div>
<h1><div id="ledstatus"></div>
<button id="ledon" type="button" onclick="buttonclick(this);">On</button>
<button id="ledoff" type="button" onclick="buttonclick(this);">Off</button></h1>
</body>
</html>
)rawliteral";
const int LEDPIN = D4;
const int POWERPIN = D1;
String TempVal;
bool LEDStatus;
// Commands sent through Web Socket
const char LEDON[] = "ledon";
const char LEDOFF[] = "ledoff";
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
Serial.printf("webSocketEvent(%d, %d, ...)\r\n", num, type);
switch(type) {
case WStype_DISCONNECTED:
Serial.printf("[%u] Disconnected!\r\n", num);
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(num);
Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);
// temp request
sensors.requestTemperatures();
// Send the current LED status and temperature
if (LEDStatus) {
TempVal = "ledon " + String(sensors.getTempCByIndex(0));
webSocket.sendTXT(num, TempVal);
}
else {
TempVal = "ledoff" + String(sensors.getTempCByIndex(0));
webSocket.sendTXT(num, TempVal);
}
}
break;
case WStype_TEXT:
Serial.printf("[%u] get Text: %s\r\n", num, payload);
if (strcmp(LEDON, (const char *)payload) == 0) {
writeLED(true);
}
else if (strcmp(LEDOFF, (const char *)payload) == 0) {
writeLED(false);
}
else {
Serial.println("Unknown command");
}
// send data to all connected clients
webSocket.broadcastTXT(payload, length);
break;
case WStype_BIN:
Serial.printf("[%u] get binary length: %u\r\n", num, length);
hexdump(payload, length);
// echo data back to browser
webSocket.sendBIN(num, payload, length);
break;
default:
Serial.printf("Invalid WStype [%d]\r\n", type);
break;
}
}
void handleRoot()
{
server.send_P(200, "text/html", INDEX_HTML);
}
void handleNotFound()
{
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
static void writeLED(bool LEDon)
{
LEDStatus = LEDon;
// Note inverted logic for Adafruit HUZZAH board
if (LEDon) {
digitalWrite(LEDPIN, 0);
digitalWrite(POWERPIN, 1);
}
else {
digitalWrite(LEDPIN, 1);
digitalWrite(POWERPIN, 0);
}
}
void setup()
{
pinMode(LEDPIN, OUTPUT);
pinMode(POWERPIN, OUTPUT);
digitalWrite(POWERPIN, 0);
writeLED(false);
Serial.begin(115200);
//Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
for(uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] BOOT WAIT %d...\r\n", t);
Serial.flush();
delay(1000);
}
WiFiMulti.addAP(ssid, password);
while(WiFiMulti.run() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (mdns.begin("espWebSock", WiFi.localIP())) {
Serial.println("MDNS responder started");
mdns.addService("http", "tcp", 80);
mdns.addService("ws", "tcp", 81);
}
else {
Serial.println("MDNS.begin failed");
}
Serial.print("Connect to http://");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
server.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
//temp setup
sensors.begin();
}
void loop()
{
webSocket.loop();
server.handleClient();
}
Spent a lot of time to see temperature sensor data from Webserver, also to control my boiler via Relay.
Strange bug: server works perfectly from PC internally or from external IP. But with mobile phones works internally, but from external IP hangs up and does not load the page...
Please help to understand where is the problem. Here is the code:
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <Hash.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
//temp libraries
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS D2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
static const char ssid[] = "ssid";
static const char password[] = "password";
MDNSResponder mdns;
static void writeLED(bool);
ESP8266WiFiMulti WiFiMulti;
ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<!DOCTYPE html><html><head><style>@import url(https://fonts.googleapis.com/css?family ... 00,500,600);
#element1 { width:200px; height:200px; border-radius:25%; display:inline-block;
background: green; background:-webkit-linear-gradient(red, blue); background:-o-linear-gradient(red, blue);
background: -moz-linear-gradient(red, blue);background: linear-gradient(red, blue); }
#element2 { width:160px; height:160px; border-radius:20%; display:inline-block; background:#e3e3e4; margin-top:20px; }
#tekstas { position:relative; left:-10px; top: 5px; }
.txt { text-align:center; font-family:'Dosis'; color:maroon; }
.txt strong { font-size:115px; }
.txt span { position:absolute; font-size:30px; left:135px; top:45px; }
</style>
<script>
var websock;
function start() {
websock = new WebSocket('ws://' + window.location.hostname + ':81/');
websock.onopen = function(evt) { console.log('websock open'); }
websock.onclose = function(evt) { console.log('websock close'); }
websock.onerror = function(evt) { console.log(evt); }
websock.onmessage = function(evt) {
console.log(evt);
var e = document.getElementById('ledstatus');
var t1 = document.getElementById('temp1');
var t2 = document.getElementById('temp2');
if (evt.data.includes('ledon')) {
e.style.color = 'red';
e.textContent = 'ON';
}
else if (evt.data.includes('ledoff')) {
e.style.color = 'black';
e.textContent = 'OFF';
}
else {
console.log('unknown event');
}
if (evt.data.length > 6) {
t1.textContent = evt.data.substring(6,8);
t2.textContent = evt.data.substring(8);
}
}
}
function buttonclick(e) {
websock.send(e.id);
}
</script>
</head>
<body class="txt" onload="javascript:start();">
<h1>Namai, Ateities 77</h1>
<div><div id="element1"><div id="element2"><div id="tekstas">
<strong id="temp1"></strong>
<span id="temp2"></span>
</div></div></div></div>
<h1><div id="ledstatus"></div>
<button id="ledon" type="button" onclick="buttonclick(this);">On</button>
<button id="ledoff" type="button" onclick="buttonclick(this);">Off</button></h1>
</body>
</html>
)rawliteral";
const int LEDPIN = D4;
const int POWERPIN = D1;
String TempVal;
bool LEDStatus;
// Commands sent through Web Socket
const char LEDON[] = "ledon";
const char LEDOFF[] = "ledoff";
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
Serial.printf("webSocketEvent(%d, %d, ...)\r\n", num, type);
switch(type) {
case WStype_DISCONNECTED:
Serial.printf("[%u] Disconnected!\r\n", num);
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(num);
Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);
// temp request
sensors.requestTemperatures();
// Send the current LED status and temperature
if (LEDStatus) {
TempVal = "ledon " + String(sensors.getTempCByIndex(0));
webSocket.sendTXT(num, TempVal);
}
else {
TempVal = "ledoff" + String(sensors.getTempCByIndex(0));
webSocket.sendTXT(num, TempVal);
}
}
break;
case WStype_TEXT:
Serial.printf("[%u] get Text: %s\r\n", num, payload);
if (strcmp(LEDON, (const char *)payload) == 0) {
writeLED(true);
}
else if (strcmp(LEDOFF, (const char *)payload) == 0) {
writeLED(false);
}
else {
Serial.println("Unknown command");
}
// send data to all connected clients
webSocket.broadcastTXT(payload, length);
break;
case WStype_BIN:
Serial.printf("[%u] get binary length: %u\r\n", num, length);
hexdump(payload, length);
// echo data back to browser
webSocket.sendBIN(num, payload, length);
break;
default:
Serial.printf("Invalid WStype [%d]\r\n", type);
break;
}
}
void handleRoot()
{
server.send_P(200, "text/html", INDEX_HTML);
}
void handleNotFound()
{
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
static void writeLED(bool LEDon)
{
LEDStatus = LEDon;
// Note inverted logic for Adafruit HUZZAH board
if (LEDon) {
digitalWrite(LEDPIN, 0);
digitalWrite(POWERPIN, 1);
}
else {
digitalWrite(LEDPIN, 1);
digitalWrite(POWERPIN, 0);
}
}
void setup()
{
pinMode(LEDPIN, OUTPUT);
pinMode(POWERPIN, OUTPUT);
digitalWrite(POWERPIN, 0);
writeLED(false);
Serial.begin(115200);
//Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
for(uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] BOOT WAIT %d...\r\n", t);
Serial.flush();
delay(1000);
}
WiFiMulti.addAP(ssid, password);
while(WiFiMulti.run() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (mdns.begin("espWebSock", WiFi.localIP())) {
Serial.println("MDNS responder started");
mdns.addService("http", "tcp", 80);
mdns.addService("ws", "tcp", 81);
}
else {
Serial.println("MDNS.begin failed");
}
Serial.print("Connect to http://");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
server.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
//temp setup
sensors.begin();
}
void loop()
{
webSocket.loop();
server.handleClient();
}