Skip to content

esp8266: share port 80 with regular webserver #575

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Nov 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* WebSocketServerHooked.ino
*
* Created on: 22.05.2015
* Hooked on: 28.10.2020
*
*/

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSockets4WebServer.h>
#include <Hash.h>
#include <ESP8266mDNS.h>

ESP8266WiFiMulti WiFiMulti;

ESP8266WebServer server(80);
WebSockets4WebServer webSocket;

#define USE_SERIAL Serial

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {

switch(type) {
case WStype_DISCONNECTED:
USE_SERIAL.printf("[%u] Disconnected!\n", num);
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(num);
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);

// send message to client
webSocket.sendTXT(num, "Connected");
}
break;
case WStype_TEXT:
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);

// send message to client
// webSocket.sendTXT(num, "message here");

// send data to all connected clients
// webSocket.broadcastTXT("message here");
break;
case WStype_BIN:
USE_SERIAL.printf("[%u] get binary length: %u\n", num, length);
hexdump(payload, length);

// send message to client
// webSocket.sendBIN(num, payload, length);
break;
}

}

void setup() {
// USE_SERIAL.begin(921600);
USE_SERIAL.begin(115200);

//Serial.setDebugOutput(true);
USE_SERIAL.setDebugOutput(true);

USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();

for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}

WiFiMulti.addAP("SSID", "passpasspass");

while(WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}

server.on("/", []() {
server.send(200, "text/plain", "I am a regular webserver on port 80!\r\n");
server.send(200, "text/plain", "I am also a websocket server on '/ws' on the same port 80\r\n");
});

server.addHook(webSocket.hookForWebserver("/ws", webSocketEvent));

server.begin();
Serial.println("HTTP server started on port 80");
Serial.println("WebSocket server started on the same port");
Serial.printf("my network address is either 'arduinoWebsockets.local' (mDNS) or '%s'\n", WiFi.localIP().toString().c_str());

if (!MDNS.begin("arduinoWebsockets")) {
Serial.println("Error setting up MDNS responder!");
}
}

void loop() {
server.handleClient();
webSocket.loop();
MDNS.update();
}
20 changes: 20 additions & 0 deletions examples/esp8266/WebSocketServerHooked/emu
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh

# linux script to compile&run arduinoWebSockets in a mock environment

if [ -z "$ESP8266ARDUINO" ]; then
echo "please set ESP8266ARDUINO env-var to where esp8266/arduino sits"
exit 1
fi

set -e

where=$(pwd)

cd $ESP8266ARDUINO/tests/host/

make -j FORCE32=0 \
ULIBDIRS=../../libraries/Hash/:~/dev/proj/arduino/libraries/arduinoWebSockets \
${where}/WebSocketServerHooked

valgrind ./bin/WebSocketServerHooked/WebSocketServerHooked -b "$@"
45 changes: 45 additions & 0 deletions examples/esp8266/WebSocketServerHooked/ws-testclient.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env python3

# python websocket client to test with
# emulator: server is at ws://127.0.0.1:9080/ws
# esp8266: server is at ws:///ws
# (uncomment the right line below)

#uri = "ws://127.0.0.1:9080/ws"
uri = "ws://arduinoWebsockets.local/ws"

import websocket
try:
import thread
except ImportError:
import _thread as thread
import time

def on_message(ws, message):
print("message");
print(message)

def on_error(ws, error):
print("error")
print(error)

def on_close(ws):
print("### closed ###")

def on_open(ws):
print("opened")
def run(*args):
for i in range(3):
time.sleep(1)
ws.send("Hello %d" % i)
time.sleep(1)
ws.close()
print("thread terminating...")
thread.start_new_thread(run, ())


if __name__ == "__main__":
websocket.enableTrace(True)
ws = websocket.WebSocketApp(uri, on_message = on_message, on_error = on_error, on_close = on_close)
ws.on_open = on_open
ws.run_forever()
2 changes: 1 addition & 1 deletion src/WebSockets.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

#ifndef NODEBUG_WEBSOCKETS
#ifdef DEBUG_ESP_PORT
#define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf(__VA_ARGS__)
#define DEBUG_WEBSOCKETS(...) { DEBUG_ESP_PORT.printf(__VA_ARGS__); DEBUG_ESP_PORT.flush(); }
#else
//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ )
#endif
Expand Down
76 changes: 76 additions & 0 deletions src/WebSockets4WebServer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* @file WebSocketsServer.cpp
* @date 28.10.2020
* @author Markus Sattler & esp8266/arduino community
*
* Copyright (c) 2020 Markus Sattler. All rights reserved.
* This file is part of the WebSockets for Arduino.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

#ifndef __WEBSOCKETS4WEBSERVER_H
#define __WEBSOCKETS4WEBSERVER_H

#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>

#if WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK

class WebSockets4WebServer: public WebSocketsServerCore {
public:

WebSockets4WebServer(const String& origin = "", const String& protocol = "arduino"):
WebSocketsServerCore(origin, protocol)
{
begin();
}

ESP8266WebServer::HookFunction hookForWebserver (const String& wsRootDir, WebSocketServerEvent event)
{
onEvent(event);

return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType)
{
if (!(method == "GET" && url.indexOf(wsRootDir) == 0)) {
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
}

// allocate a WiFiClient copy (like in WebSocketsServer::handleNewClients())
WEBSOCKETS_NETWORK_CLASS * newTcpClient = new WEBSOCKETS_NETWORK_CLASS(*tcpClient);

// Then initialize a new WSclient_t (like in WebSocketsServer::handleNewClient())
WSclient_t * client = handleNewClient(newTcpClient);

if (client)
{
// give "GET <url>"
String headerLine;
headerLine.reserve(url.length() + 5);
headerLine = "GET ";
headerLine += url;
handleHeader(client, &headerLine);
}

// tell webserver to not close but forget about this client
return ESP8266WebServer::CLIENT_IS_GIVEN;
};
}
};

#endif // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK

#endif // __WEBSOCKETS4WEBSERVER_H
Loading