Add server sent events, change vfs structure, dark mode error pages and dark mode anonydrop
This commit is contained in:
@@ -6,6 +6,7 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
PACKAGE_AND_BREW: ${{ secrets.PACKAGE_AND_BREW }}
|
PACKAGE_AND_BREW: ${{ secrets.PACKAGE_AND_BREW }}
|
||||||
|
VERSION: ${{ gitea.ref_name }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-arch:
|
build-arch:
|
||||||
@@ -20,3 +21,22 @@ jobs:
|
|||||||
- run: chown build:build /home/build/PKGBUILD
|
- run: chown build:build /home/build/PKGBUILD
|
||||||
- run: chown build:build /home/build/build-arch.sh
|
- run: chown build:build /home/build/build-arch.sh
|
||||||
- run: su build -c /home/build/build-arch.sh
|
- run: su build -c /home/build/build-arch.sh
|
||||||
|
|
||||||
|
update-tap:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: "master"
|
||||||
|
path: "tapdir"
|
||||||
|
repository: "tesses50/tesses-tap.git"
|
||||||
|
token: ${{ env.PACKAGE_AND_BREW }}
|
||||||
|
- run: |
|
||||||
|
cd tapdir
|
||||||
|
bash ../Packaging/edit-formula.sh
|
||||||
|
git config user.name "Tesses Gitea Bot"
|
||||||
|
git config user.email "noreply@tesses.net"
|
||||||
|
git add .
|
||||||
|
git commit -m "Push tesses-framework=${{ env.VERSION }}"
|
||||||
|
git push
|
||||||
|
|||||||
19
Packaging/edit-formula.sh
Normal file
19
Packaging/edit-formula.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export HASH=`curl https://git.tesses.org/tesses50/tessesframework/archive/$VERSION.tar.gz 2> /dev/null | shasum -a 256 | awk '{print $1}'`
|
||||||
|
|
||||||
|
echo "class Tessesframework < Formula" > "Formula/tessesframework.rb"
|
||||||
|
echo " desc \"\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " homepage \"\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " url \"https://git.tesses.org/tesses50/tessesframework/archive/$VERSION.tar.gz\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " sha256 \"$HASH\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " license \"MIT\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " depends_on \"cmake\" => :build" >> "Formula/tessesframework.rb"
|
||||||
|
echo " depends_on \"mbedtls@3\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " def install" >> "Formula/tessesframework.rb"
|
||||||
|
echo " system \"cmake\", \"-S\", \".\", \"-B\", \"build\", \"-DTESSESFRAMEWORK_FETCHCONTENT=OFF\", *std_cmake_args" >> "Formula/tessesframework.rb"
|
||||||
|
echo " system \"cmake\", \"--build\", \"build\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " system \"cmake\", \"--install\", \"build\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " end" >> "Formula/tessesframework.rb"
|
||||||
|
echo " test do" >> "Formula/tessesframework.rb"
|
||||||
|
echo " system \"true\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " end" >> "Formula/tessesframework.rb"
|
||||||
|
echo "end" >> "Formula/tessesframework.rb"
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.0.3
|
||||||
|
Add server sent events, change vfs structure, dark mode error pages and dark mode anonydrop
|
||||||
|
|
||||||
## 0.0.2
|
## 0.0.2
|
||||||
Add UUIDs
|
Add UUIDs
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ using namespace Tesses::Framework::Http;
|
|||||||
using namespace Tesses::Framework::Streams;
|
using namespace Tesses::Framework::Streams;
|
||||||
using namespace Tesses::Framework::TextStreams;
|
using namespace Tesses::Framework::TextStreams;
|
||||||
using namespace Tesses::Framework::Threading;
|
using namespace Tesses::Framework::Threading;
|
||||||
|
|
||||||
|
std::shared_ptr<ServerSentEvents> sse = std::make_shared<ServerSentEvents>();
|
||||||
|
|
||||||
class Johnny : public ServerContextData
|
class Johnny : public ServerContextData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -65,7 +68,7 @@ class MyWebServer : public IHttpServer {
|
|||||||
for(size_t i=0;i<10000; i++)
|
for(size_t i=0;i<10000; i++)
|
||||||
{
|
{
|
||||||
writer.WriteLine("<li>" + std::to_string(i) + "</li>");
|
writer.WriteLine("<li>" + std::to_string(i) + "</li>");
|
||||||
|
TF_Sleep(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine("</ul>");
|
writer.WriteLine("</ul>");
|
||||||
@@ -74,6 +77,15 @@ class MyWebServer : public IHttpServer {
|
|||||||
writer.WriteLine("</html>");
|
writer.WriteLine("</html>");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if(ctx.path == "/ssetest.html")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(ctx.path == "/sse")
|
||||||
|
{
|
||||||
|
ctx.SendServerSentEvents(sse);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if(ctx.path == "/main.js")
|
else if(ctx.path == "/main.js")
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -162,6 +174,13 @@ class MyOtherWebServer : public IHttpServer
|
|||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
TF_InitWithConsole();
|
TF_InitWithConsole();
|
||||||
|
int64_t timer = 0;
|
||||||
|
auto timerHDL= TF_Timer([&timer]()->void{
|
||||||
|
timer++;
|
||||||
|
|
||||||
|
sse->SendData("Timer has ticked " + std::to_string(timer) + " times now");
|
||||||
|
});
|
||||||
|
|
||||||
std::shared_ptr<RouteServer> routeSvr = std::make_shared<RouteServer>();
|
std::shared_ptr<RouteServer> routeSvr = std::make_shared<RouteServer>();
|
||||||
routeSvr->Get("/name/{name}/greeting",[](ServerContext& ctx)->bool{
|
routeSvr->Get("/name/{name}/greeting",[](ServerContext& ctx)->bool{
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ namespace Tesses::Framework
|
|||||||
void TF_RunEventLoop();
|
void TF_RunEventLoop();
|
||||||
void TF_RunEventLoopItteration();
|
void TF_RunEventLoopItteration();
|
||||||
bool TF_IsRunning();
|
bool TF_IsRunning();
|
||||||
|
void TF_Sleep(uint32_t sleepMS);
|
||||||
void TF_SetIsRunning(bool _isRunning);
|
void TF_SetIsRunning(bool _isRunning);
|
||||||
void TF_Quit();
|
void TF_Quit();
|
||||||
bool TF_GetConsoleEventsEnabled();
|
bool TF_GetConsoleEventsEnabled();
|
||||||
|
|||||||
@@ -13,12 +13,30 @@ namespace Tesses::Framework::Http
|
|||||||
public:
|
public:
|
||||||
virtual ~ServerContextData();
|
virtual ~ServerContextData();
|
||||||
};
|
};
|
||||||
|
class ServerContext;
|
||||||
|
class ServerSentEvents {
|
||||||
|
std::vector<std::shared_ptr<Tesses::Framework::Streams::Stream>> strms;
|
||||||
|
Tesses::Framework::Threading::Mutex mtx;
|
||||||
|
private:
|
||||||
|
void SendEventRaw(const std::string& evt);
|
||||||
|
public:
|
||||||
|
void SendRetry(uint32_t ms);
|
||||||
|
void SendRetry(std::chrono::milliseconds ms);
|
||||||
|
void SendRetry(Tesses::Framework::Date::TimeSpan ts);
|
||||||
|
void SendData(const std::string& message);
|
||||||
|
void SendData(const std::string& message, const std::string& dataType);
|
||||||
|
void SendId(const std::string& idVal);
|
||||||
|
void SendCustomEvent(const std::string& type, const std::string& value);
|
||||||
|
void SendComment(const std::string& comment);
|
||||||
|
friend class ServerContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class ServerContext {
|
class ServerContext {
|
||||||
|
|
||||||
bool sent;
|
bool sent;
|
||||||
bool debug;
|
bool debug;
|
||||||
|
std::vector<std::shared_ptr<ServerSentEvents>> sse;
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||||
std::map<std::string,ServerContextData*> data;
|
std::map<std::string,ServerContextData*> data;
|
||||||
std::queue<std::function<bool(ServerContext& ctx)>> headerhandlers;
|
std::queue<std::function<bool(ServerContext& ctx)>> headerhandlers;
|
||||||
@@ -54,6 +72,7 @@ namespace Tesses::Framework::Http
|
|||||||
void SendNotFound();
|
void SendNotFound();
|
||||||
void SendBadRequest();
|
void SendBadRequest();
|
||||||
void SendException(std::exception& ex);
|
void SendException(std::exception& ex);
|
||||||
|
void SendServerSentEvents(std::shared_ptr<ServerSentEvents> sse);
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenResponseStream();
|
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenResponseStream();
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenRequestStream();
|
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenRequestStream();
|
||||||
ServerContext& WithStatusCode(StatusCode code);
|
ServerContext& WithStatusCode(StatusCode code);
|
||||||
@@ -87,6 +106,9 @@ namespace Tesses::Framework::Http
|
|||||||
data[name] = item;
|
data[name] = item;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
friend class ServerSentEvents;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IHttpServer {
|
class IHttpServer {
|
||||||
|
|||||||
@@ -46,12 +46,17 @@ namespace Tesses::Framework::Streams
|
|||||||
void Listen(int32_t backlog);
|
void Listen(int32_t backlog);
|
||||||
void Bind(std::string ip, uint16_t port);
|
void Bind(std::string ip, uint16_t port);
|
||||||
void SetBroadcast(bool bC);
|
void SetBroadcast(bool bC);
|
||||||
|
void SetReuseAddress(bool reuse);
|
||||||
|
void SetReusePort(bool reuse);
|
||||||
|
void SetMulticastTTL(uint8_t ttl);
|
||||||
|
void SetMulticastMembership(std::string multicastAddress, std::string ifaceIP="0.0.0.0");
|
||||||
std::shared_ptr<NetworkStream> Accept(std::string& ip, uint16_t& port);
|
std::shared_ptr<NetworkStream> Accept(std::string& ip, uint16_t& port);
|
||||||
size_t Read(uint8_t* buff, size_t sz);
|
size_t Read(uint8_t* buff, size_t sz);
|
||||||
size_t Write(const uint8_t* buff, size_t sz);
|
size_t Write(const uint8_t* buff, size_t sz);
|
||||||
size_t ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port);
|
size_t ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port);
|
||||||
size_t WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port);
|
size_t WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port);
|
||||||
static std::vector<std::pair<std::string,std::string>> GetIPs(bool ipV6=false);
|
static std::vector<std::pair<std::string,std::string>> GetIPs(bool ipV6=false);
|
||||||
|
|
||||||
~NetworkStream();
|
~NetworkStream();
|
||||||
void SetNoDelay(bool noDelay);
|
void SetNoDelay(bool noDelay);
|
||||||
void Close();
|
void Close();
|
||||||
|
|||||||
@@ -27,6 +27,79 @@ using namespace Tesses::Framework::TextStreams;
|
|||||||
|
|
||||||
namespace Tesses::Framework::Http
|
namespace Tesses::Framework::Http
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void ServerSentEvents::SendEventRaw(const std::string& evt)
|
||||||
|
{
|
||||||
|
this->mtx.Lock();
|
||||||
|
for(auto& item : this->strms)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
StreamWriter writer(item);
|
||||||
|
writer.newline = "\r\n";
|
||||||
|
writer.WriteLine(evt);
|
||||||
|
|
||||||
|
|
||||||
|
}catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->mtx.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSentEvents::SendId(const std::string& id)
|
||||||
|
{
|
||||||
|
SendCustomEvent("id",id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSentEvents::SendData(const std::string& message)
|
||||||
|
{
|
||||||
|
SendCustomEvent("data", message);
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendComment(const std::string& comment)
|
||||||
|
{
|
||||||
|
SendCustomEvent("", comment);
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendCustomEvent(const std::string& etype, const std::string& message)
|
||||||
|
{
|
||||||
|
std::string text = etype + ": ";
|
||||||
|
for(auto item : message)
|
||||||
|
{
|
||||||
|
if(item == '\r') continue;
|
||||||
|
if(item == '\n') {
|
||||||
|
text += "\r\n" + etype + ": ";
|
||||||
|
}
|
||||||
|
else text += item;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendEventRaw(text);
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendData(const std::string& message, const std::string& mtype)
|
||||||
|
{
|
||||||
|
std::string text = "event: " + mtype + "\r\ndata: ";
|
||||||
|
for(auto item : message)
|
||||||
|
{
|
||||||
|
if(item == '\r') continue;
|
||||||
|
if(item == '\n') {
|
||||||
|
text += "\r\ndata: ";
|
||||||
|
}
|
||||||
|
else text += item;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendEventRaw(text);
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendRetry(uint32_t ms)
|
||||||
|
{
|
||||||
|
SendCustomEvent("retry", std::to_string(ms));
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendRetry(std::chrono::milliseconds ms)
|
||||||
|
{
|
||||||
|
SendCustomEvent("retry", std::to_string(ms.count()));
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendRetry(Tesses::Framework::Date::TimeSpan ts)
|
||||||
|
{
|
||||||
|
SendRetry((uint32_t)ts.TotalSeconds() * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
class WSServer
|
class WSServer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -282,6 +355,7 @@ namespace Tesses::Framework::Http
|
|||||||
this->conn->OnClose(false);
|
this->conn->OnClose(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int _header_field(multipart_parser* p, const char *at, size_t length)
|
static int _header_field(multipart_parser* p, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
@@ -344,6 +418,7 @@ namespace Tesses::Framework::Http
|
|||||||
data->currentHeaders.Clear();
|
data->currentHeaders.Clear();
|
||||||
return 0;
|
return 0;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
std::string ServerContext::GetUrlWithQuery()
|
std::string ServerContext::GetUrlWithQuery()
|
||||||
{
|
{
|
||||||
if(this->queryParams.kvp.empty()) return this->path;
|
if(this->queryParams.kvp.empty()) return this->path;
|
||||||
@@ -364,6 +439,34 @@ namespace Tesses::Framework::Http
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ServerContext::SendServerSentEvents(std::shared_ptr<ServerSentEvents> sse)
|
||||||
|
{
|
||||||
|
this->responseHeaders.SetValue("X-Accel-Buffering","no");
|
||||||
|
this->responseHeaders.SetValue("Content-Type","text/event-stream");
|
||||||
|
this->responseHeaders.SetValue("Cache-Control","no-cache");
|
||||||
|
auto strm = this->OpenResponseStream();
|
||||||
|
if(strm == nullptr || this->method == "HEAD") return;
|
||||||
|
sse->mtx.Lock();
|
||||||
|
sse->strms.push_back(strm);
|
||||||
|
sse->mtx.Unlock();
|
||||||
|
while(!this->strm->EndOfStream())
|
||||||
|
{
|
||||||
|
TF_Sleep(10);
|
||||||
|
}
|
||||||
|
sse->mtx.Lock();
|
||||||
|
for(auto index = sse->strms.begin(); index != sse->strms.end(); index++)
|
||||||
|
{
|
||||||
|
if(*index == strm)
|
||||||
|
{
|
||||||
|
sse->strms.erase(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sse->mtx.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
std::string ServerContext::ReadString()
|
std::string ServerContext::ReadString()
|
||||||
{
|
{
|
||||||
if(strm == nullptr) return {};
|
if(strm == nullptr) return {};
|
||||||
|
|||||||
@@ -160,20 +160,30 @@ namespace Tesses::Framework::Http
|
|||||||
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
||||||
{
|
{
|
||||||
this->done=true;
|
this->done=true;
|
||||||
|
try {
|
||||||
|
|
||||||
StreamWriter writer(this->strm);
|
StreamWriter writer(this->strm);
|
||||||
writer.newline = "\r\n";
|
writer.newline = "\r\n";
|
||||||
writer.WriteLine("0");
|
writer.WriteLine("0");
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
|
}catch(...){
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HttpStream::~HttpStream()
|
HttpStream::~HttpStream()
|
||||||
{
|
{
|
||||||
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
StreamWriter writer(this->strm);
|
StreamWriter writer(this->strm);
|
||||||
writer.newline = "\r\n";
|
writer.newline = "\r\n";
|
||||||
writer.WriteLine("0");
|
writer.WriteLine("0");
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
|
}catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
#include "TessesFramework/Streams/NetworkStream.hpp"
|
#include "TessesFramework/Streams/NetworkStream.hpp"
|
||||||
#include "TessesFramework/Http/HttpUtils.hpp"
|
#include "TessesFramework/Http/HttpUtils.hpp"
|
||||||
|
#include <TessesFramework/Streams/NetworkStream.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
||||||
|
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_NETWORKING)
|
#if defined(TESSESFRAMEWORK_ENABLE_NETWORKING)
|
||||||
|
|
||||||
|
|
||||||
@@ -34,6 +36,8 @@ using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
|||||||
#endif
|
#endif
|
||||||
#undef min
|
#undef min
|
||||||
#pragma comment(lib, "ws2_32.lib")
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -47,6 +51,7 @@ extern "C" {
|
|||||||
#if defined(AF_UNIX) && !defined(GEKKO) && !defined(__SWITCH__) && !defined(__PS2__)
|
#if defined(AF_UNIX) && !defined(GEKKO) && !defined(__SWITCH__) && !defined(__PS2__)
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -720,10 +725,75 @@ namespace Tesses::Framework::Streams {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void NetworkStream::SetReuseAddress(bool reuse)
|
||||||
|
{
|
||||||
|
if(!this->success) return;
|
||||||
|
int no = reuse ? 1 : 0;
|
||||||
|
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&no, sizeof(no)) != 0)
|
||||||
|
{
|
||||||
|
this->success=false;
|
||||||
|
if(this->owns)
|
||||||
|
NETWORK_CLOSE(this->sock);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void NetworkStream::SetReusePort(bool reuse)
|
||||||
|
{
|
||||||
|
if(!this->success) return;
|
||||||
|
int no = reuse ? 1 : 0;
|
||||||
|
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&no, sizeof(no)) != 0)
|
||||||
|
{
|
||||||
|
this->success=false;
|
||||||
|
if(this->owns)
|
||||||
|
NETWORK_CLOSE(this->sock);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void NetworkStream::SetMulticastTTL(uint8_t ttl)
|
||||||
|
{
|
||||||
|
if(!this->success) return;
|
||||||
|
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
|
||||||
|
if (NETWORK_SETSOCKOPT(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl)) != 0)
|
||||||
|
{
|
||||||
|
this->success=false;
|
||||||
|
if(this->owns)
|
||||||
|
NETWORK_CLOSE(this->sock);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void NetworkStream::SetMulticastMembership(std::string multicastAddress, std::string ifaceIP)
|
||||||
|
{
|
||||||
|
if(!this->success) return;
|
||||||
|
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
|
||||||
|
struct sockaddr_storage maddr;
|
||||||
|
struct sockaddr_storage iaddr;
|
||||||
|
|
||||||
|
bool success = IPParse(multicastAddress, &maddr) && IPParse(ifaceIP, &iaddr);
|
||||||
|
if(success && maddr.ss_family == AF_INET && iaddr.ss_family == AF_INET)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ip_mreq req;
|
||||||
|
req.imr_multiaddr = ((struct sockaddr_in*)&maddr)->sin_addr;
|
||||||
|
req.imr_interface = ((struct sockaddr_in*)&iaddr)->sin_addr;
|
||||||
|
|
||||||
|
if(NETWORK_SETSOCKOPT(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&req, sizeof(req)) != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
this->success=false;
|
||||||
|
if(this->owns)
|
||||||
|
NETWORK_CLOSE(this->sock);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkStream::SetBroadcast(bool bC)
|
void NetworkStream::SetBroadcast(bool bC)
|
||||||
{
|
{
|
||||||
if(!this->success) return;
|
if(!this->success) return;
|
||||||
int broadcast = 1;
|
int broadcast = bC ? 1 : 0;
|
||||||
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)) != 0)
|
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)) != 0)
|
||||||
{
|
{
|
||||||
this->success=false;
|
this->success=false;
|
||||||
@@ -906,6 +976,23 @@ void NetworkStream::SetBroadcast(bool bC)
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
void NetworkStream::SetReuseAddress(bool reuse)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void NetworkStream::SetReusePort(bool reuse)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void NetworkStream::SetMulticastTTL(uint8_t ttl)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void NetworkStream::SetMulticastMembership(std::string multicastAddress, std::string ifaceIP="0.0.0.0")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<NetworkStream> NetworkStream::Accept(std::string& ip, uint16_t& port)
|
std::shared_ptr<NetworkStream> NetworkStream::Accept(std::string& ip, uint16_t& port)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ namespace Tesses::Framework::Streams {
|
|||||||
read = len;
|
read = len;
|
||||||
if(read > 0)
|
if(read > 0)
|
||||||
{
|
{
|
||||||
|
size_t r0=read;
|
||||||
read=this->Write(buffer,read);
|
read=this->Write(buffer,read);
|
||||||
|
|
||||||
if(read == 0)
|
if(read == 0)
|
||||||
{
|
{
|
||||||
throw std::out_of_range("Failed to write!");
|
throw std::out_of_range("Failed to write!");
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ static GXRModeObj *rmode = NULL;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace Tesses::Framework
|
namespace Tesses::Framework
|
||||||
{
|
{
|
||||||
@@ -85,7 +89,19 @@ namespace Tesses::Framework
|
|||||||
cb();
|
cb();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
void TF_Sleep(uint32_t sleepMS)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
Sleep((DWORD)sleepMS);
|
||||||
|
#else
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
ts.tv_sec = (time_t)(sleepMS / 1000);
|
||||||
|
ts.tv_nsec = (sleepMS % 1000) * 1000000;
|
||||||
|
|
||||||
|
nanosleep(&ts,NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
void TF_ConnectToSelf(uint16_t port)
|
void TF_ConnectToSelf(uint16_t port)
|
||||||
{
|
{
|
||||||
Tesses::Framework::Streams::NetworkStream ns("127.0.0.1",port,false,false,false);
|
Tesses::Framework::Streams::NetworkStream ns("127.0.0.1",port,false,false,false);
|
||||||
|
|||||||
Reference in New Issue
Block a user