diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml
new file mode 100644
index 0000000..23ef350
--- /dev/null
+++ b/.github/workflows/style.yml
@@ -0,0 +1,16 @@
+name: Check Style
+
+on: [push, pull_request]
+
+jobs:
+ style:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 7.4
+ - name: Checkout module
+ uses: actions/checkout@master
+ - name: Check style
+ uses: Nall-chan/action-style@master
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..e6563d0
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,14 @@
+name: Run Tests
+
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout module
+ uses: actions/checkout@master
+ with:
+ submodules: true
+ - name: Run tests
+ uses: symcon/action-tests@master
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..18a56a6
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,9 @@
+[submodule "tests/stubs"]
+ path = tests/stubs
+ url = https://github.com/Nall-chan/SymconStubs
+[submodule ".vscode"]
+ path = .vscode
+ url = https://github.com/Nall-chan/SymconVSCTasks.git
+[submodule ".style"]
+ path = .style
+ url = https://github.com/Nall-chan/StylePHP
diff --git a/.style b/.style
new file mode 160000
index 0000000..db94317
--- /dev/null
+++ b/.style
@@ -0,0 +1 @@
+Subproject commit db94317399d4ad0cac9220616961df392aad41c5
diff --git a/.styleci.yml b/.styleci.yml
deleted file mode 100644
index 1f535fe..0000000
--- a/.styleci.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-## YAML Template.
----
-preset: recommended
-
-enabled:
- - concat_with_spaces
-
-
-disabled:
- - trailing_comma_in_multiline_array
- - concat_without_spaces
- - blank_line_before_return
- - no_useless_return
- - simplified_null_return
\ No newline at end of file
diff --git a/.vscode b/.vscode
new file mode 160000
index 0000000..672a096
--- /dev/null
+++ b/.vscode
@@ -0,0 +1 @@
+Subproject commit 672a096abc8fcc6afa43f4aedd47821b5583b4c5
diff --git a/ClientSplitter/README.md b/ClientSplitter/README.md
index 98429ba..ad6ae30 100644
--- a/ClientSplitter/README.md
+++ b/ClientSplitter/README.md
@@ -1,4 +1,4 @@
-# ClientSplitter (IPSNetwork)
+# ClientSplitter (Network)
Implementierung eines Splitters für ServerSocket und WebSocket-Server.
@@ -31,7 +31,7 @@ Implementierung eines Splitters für ServerSocket und WebSocket-Server.
## 3. Installation
Über das Modul-Control folgende URL hinzufügen.
- `git://github.com/Nall-chan/IPSNetwork.git`
+ `git://github.com/Nall-chan/Network.git`
**Bei kommerzieller Nutzung (z.B. als Errichter oder Integrator) wenden Sie sich bitte an den Autor.**
@@ -59,15 +59,15 @@ Implementierung eines Splitters für ServerSocket und WebSocket-Server.
GUID des Modules (z.B. wenn Instanz per PHP angelegt werden soll):
-| Instanz | GUID |
-| :--------------: | :------------------------------------: |
-| Client Splitter | {7A107D38-75ED-47CB-83F9-F41228CAEEFA} |
+| Instanz | GUID |
+| :-------------: | :------------------------------------: |
+| Client Splitter | {7A107D38-75ED-47CB-83F9-F41228CAEEFA} |
Eigenschaften des 'Client Splitter' für Get/SetProperty-Befehle:
-| Eigenschaft | Typ | Standardwert | Funktion |
-| :-----------: | :-----: | :----------: | :-----------------------: |
-| ClientIP | string | | Die IP-Adresse des Client |
+| Eigenschaft | Typ | Standardwert | Funktion |
+| :---------: | :----: | :----------: | :-----------------------: |
+| ClientIP | string | | Die IP-Adresse des Client |
## 8. Datenaustausch
@@ -79,7 +79,7 @@ Kompatibel zum Interface Virtual-IO.
**Changlog:**
Version 1.1:
- - In IPSNetwork-Library integriert
+ - In Network-Library integriert
Version 1.0:
- Erstes offizielles Release
diff --git a/ClientSplitter/form.json b/ClientSplitter/form.json
index c727d7c..a9d9ec8 100644
--- a/ClientSplitter/form.json
+++ b/ClientSplitter/form.json
@@ -1,10 +1,9 @@
{
- "elements":
- [
- {
- "name": "ClientIP",
- "type": "ValidationTextBox",
- "caption": "Client IP:"
- }
- ]
+ "elements": [
+ {
+ "name": "ClientIP",
+ "type": "ValidationTextBox",
+ "caption": "Client IP:"
+ }
+ ]
}
\ No newline at end of file
diff --git a/ClientSplitter/module.json b/ClientSplitter/module.json
index 849f920..a94581e 100644
--- a/ClientSplitter/module.json
+++ b/ClientSplitter/module.json
@@ -3,9 +3,19 @@
"name": "ClientSplitter",
"type": 2,
"vendor": "",
- "aliases": ["Client Splitter"],
- "parentRequirements": ["{C8792760-65CF-4C53-B5C7-A30FCC84FEFE}"],
- "childRequirements": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}"],
- "implemented": ["{7A1272A4-CBDB-46EF-BFC6-DCF4A53D2FC7}", "{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}"],
- "prefix": "WSC"
+ "aliases": [
+ "Client Splitter"
+ ],
+ "parentRequirements": [
+ "{C8792760-65CF-4C53-B5C7-A30FCC84FEFE}"
+ ],
+ "childRequirements": [
+ "{018EF6B5-AB94-40C6-AA53-46943E824ACF}"
+ ],
+ "implemented": [
+ "{7A1272A4-CBDB-46EF-BFC6-DCF4A53D2FC7}",
+ "{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}"
+ ],
+ "prefix": "WSC",
+ "url": "https://github.com/Nall-chan/Network"
}
\ No newline at end of file
diff --git a/ClientSplitter/module.php b/ClientSplitter/module.php
index 2b61436..4cb65bb 100644
--- a/ClientSplitter/module.php
+++ b/ClientSplitter/module.php
@@ -1,5 +1,7 @@
ApplyChanges();
- }
-
/**
* Interne Funktion des SDK.
* Wird von der Console aufgerufen, wenn 'unser' IO-Parent geöffnet wird.
@@ -180,6 +174,7 @@ public function ReceiveData($JSONString)
{
$Data = utf8_decode(json_decode($JSONString)->Buffer);
$this->SendDebug('Data', $Data, 1);
+ $this->LogMessage(bin2hex($Data), KL_MESSAGE);
$isDHCP = (substr($Data, 236, 4) === chr(0x63) . chr(0x82) . chr(0x53) . chr(0x63));
$isDHCPRequest = (substr($Data, 236, 7) === chr(0x63) . chr(0x82) . chr(0x53) . chr(0x63) . chr(0x35) . chr(0x01) . chr(0x03));
$this->SendDebug('isDHCP', $isDHCP, 0);
@@ -198,14 +193,21 @@ public function ReceiveData($JSONString)
case 2: // both
if ($isDHCPRequest) {
$this->SendEvent();
- }
- if (!$isDHCP) {
+ } elseif (!$isDHCP) {
$this->SendEvent();
}
break;
}
}
+ /**
+ * Wird ausgeführt wenn der Kernel hochgefahren wurde.
+ */
+ protected function KernelReady()
+ {
+ $this->ApplyChanges();
+ }
+
/**
* Beschreibt die Statusvariable.
*/
@@ -214,25 +216,15 @@ protected function SendEvent()
$this->SendDebug('FIRE', 'EVENT', 0);
switch ($this->ReadPropertyInteger('Action')) {
case 0: //EVENT
- $vid = @$this->GetIDForIdent('EVENT');
- if ($vid > 0) {
- SetValueBoolean($vid, true);
- }
+ $this->SetValue('EVENT', true);
break;
case 1: // IMPULSE
- $vid = @$this->GetIDForIdent('IMPULSE');
- if ($vid > 0) {
- SetValueBoolean($vid, true);
- IPS_Sleep(1);
- SetValueBoolean($vid, false);
- }
-
+ $this->SetValue('EVENT', true);
+ IPS_Sleep(1);
+ $this->SetValue('EVENT', false);
break;
case 2: // Toggle
- $vid = @$this->GetIDForIdent('TOGGLE');
- if ($vid > 0) {
- SetValueBoolean($vid, !GetValueBoolean($vid));
- }
+ $this->SetValue('EVENT', !$this->GetValue('EVENT'));
break;
}
}
diff --git a/HookReverseProxy/README.md b/HookReverseProxy/README.md
index 0e6359a..24aacf4 100644
--- a/HookReverseProxy/README.md
+++ b/HookReverseProxy/README.md
@@ -1,4 +1,4 @@
-[![Version](https://img.shields.io/badge/Symcon-PHPModul-red.svg)](https://www.symcon.de/service/dokumentation/entwicklerbereich/sdk-tools/sdk-php/)
+[![SDK](https://img.shields.io/badge/Symcon-PHPModul-red.svg)](https://www.symcon.de/service/dokumentation/entwicklerbereich/sdk-tools/sdk-php/)
[![Version](https://img.shields.io/badge/Modul%20Version-2.20-blue.svg)]()
[![License](https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-green.svg)](https://creativecommons.org/licenses/by-nc-sa/4.0/)
[![Version](https://img.shields.io/badge/Symcon%20Version-4.3%20%3E-green.svg)](https://www.symcon.de/forum/threads/30857-IP-Symcon-4-3-%28Stable%29-Changelog)
@@ -36,11 +36,11 @@ Stellt interne Dateien und URLs als Webhook bereit
## 3. Software-Installation
- Dieses Modul ist Bestandteil der [IPSNetwork-Library](../).
+ Dieses Modul ist Bestandteil der [Network-Library](../).
**IPS 5.0:**
Bei privater Nutzung: Über das 'Module-Control' in IPS folgende URL hinzufügen.
- `git://github.com/Nall-chan/IPSNetwork.git`
+ `git://github.com/Nall-chan/Network.git`
**Bei kommerzieller Nutzung (z.B. als Errichter oder Integrator) wenden Sie sich bitte an den Autor.**
@@ -56,13 +56,13 @@ Folgende Parameter sind in der Instanz zu konfigurieren:
Werte pro Spalte:
-| Eigenschaft | Typ | Standardwert | Funktion |
-| :-----------------: | :-----: | :----------: | :------------------------------------------------------------------------------------: |
-| Hook | string | /hook/ | URI des Webhook. Muss mit /hook/ anfangen. |
-| Url | string | http:// | URL zur Quelle. Kann auch https oder eine lokale Datei sein. |
-| forceDL | bool | false | Zwingt Browser die gelieferten Daten als Datei zu speichern und nicht darzustellen. |
-| allowGet | bool | true | Erlaubt das Erweitern und Überscheiben von Parametern durch den Hook. |
-| weakSSL | bool | false | Deaktiviert die SSL Prüfung. Zum Beispiel für selbst-signierte Zertifikate. |
+| Eigenschaft | Typ | Standardwert | Funktion |
+| :---------: | :----: | :----------: | :---------------------------------------------------------------------------------: |
+| Hook | string | /hook/ | URI des Webhook. Muss mit /hook/ anfangen. |
+| Url | string | http:// | URL zur Quelle. Kann auch https oder eine lokale Datei sein. |
+| forceDL | bool | false | Zwingt Browser die gelieferten Daten als Datei zu speichern und nicht darzustellen. |
+| allowGet | bool | true | Erlaubt das Erweitern und Überscheiben von Parametern durch den Hook. |
+| weakSSL | bool | false | Deaktiviert die SSL Prüfung. Zum Beispiel für selbst-signierte Zertifikate. |
## 5. Statusvariablen und Profile
@@ -89,7 +89,7 @@ Version 2.01:
- Doku ergänzt
Version 2.0:
- - WebSocket-Module in IPSNetwork überführt
+ - WebSocket-Module in Network überführt
Version 1.0:
- Erstes offizielles Release
diff --git a/HookReverseProxy/form.json b/HookReverseProxy/form.json
index 64daeeb..914ca4e 100644
--- a/HookReverseProxy/form.json
+++ b/HookReverseProxy/form.json
@@ -1,63 +1,67 @@
{
- "elements":
- [
+ "elements": [
+ {
+ "type": "List",
+ "name": "Hooks",
+ "add": true,
+ "delete": true,
+ "sort": {
+ "column": "Hook",
+ "direction": "ascending"
+ },
+ "columns": [
{
- "type": "List",
- "name": "Hooks",
+ "caption": "IPS Hook",
+ "name": "Hook",
+ "width": "300px",
+ "add": "/hook/",
+ "edit": {
+ "caption": "URI",
+ "type": "ValidationTextBox"
+ }
+ },
+ {
+ "caption": "Source",
+ "name": "Url",
+ "width": "auto",
+ "add": "http://",
+ "edit": {
+ "caption": "URL or File",
+ "type": "ValidationTextBox"
+ }
+ },
+ {
+ "caption": "force download",
+ "name": "forceDL",
+ "width": "150px",
+ "add": false,
+ "edit": {
+ "caption": "force download",
+ "type": "CheckBox"
+ }
+ },
+ {
+ "caption": "allow get query",
+ "name": "allowGet",
+ "width": "150px",
"add": true,
- "delete": true,
- "sort": {
- "column": "Hook",
- "direction": "ascending"
- },
- "columns": [{
- "caption": "IPS Hook",
- "name": "Hook",
- "width": "300px",
- "add": "/hook/",
- "edit": {
- "caption": "URI",
- "type": "ValidationTextBox"
- }
- }, {
- "caption": "Source",
- "name": "Url",
- "width": "auto",
- "add": "http://",
- "edit": {
- "caption": "URL or File",
- "type": "ValidationTextBox"
- }
- }, {
- "caption": "force download",
- "name": "forceDL",
- "width": "150px",
- "add": false,
- "edit": {
- "caption": "force download",
- "type": "CheckBox"
- }
- }, {
- "caption": "allow get query",
- "name": "allowGet",
- "width": "150px",
- "add": true,
- "edit": {
- "caption": "allow get",
- "type": "CheckBox"
- }
- }, {
- "caption": "no SSL checks",
- "name": "weakSSL",
- "width": "150px",
- "add": false,
- "edit": {
- "caption": "no SSL checks",
- "type": "CheckBox"
- }
- }
- ],
- "values": []
+ "edit": {
+ "caption": "allow get",
+ "type": "CheckBox"
+ }
+ },
+ {
+ "caption": "no SSL checks",
+ "name": "weakSSL",
+ "width": "150px",
+ "add": false,
+ "edit": {
+ "caption": "no SSL checks",
+ "type": "CheckBox"
+ }
}
- ]
-}
+ ],
+ "values": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/HookReverseProxy/module.json b/HookReverseProxy/module.json
index ca3c8de..4188118 100644
--- a/HookReverseProxy/module.json
+++ b/HookReverseProxy/module.json
@@ -1,11 +1,14 @@
{
- "id": "{26E5D8BC-8117-4DFB-9E85-66BB30F1CF95}",
- "name": "HookReverseProxy",
- "type": 0,
- "vendor": "",
- "aliases": ["Webhook Reverse Proxy"],
- "parentRequirements": [],
- "childRequirements": [],
- "implemented": [],
- "prefix": "HOOKPROXY"
-}
+ "id": "{26E5D8BC-8117-4DFB-9E85-66BB30F1CF95}",
+ "name": "HookReverseProxy",
+ "type": 0,
+ "vendor": "",
+ "aliases": [
+ "Webhook Reverse Proxy"
+ ],
+ "parentRequirements": [],
+ "childRequirements": [],
+ "implemented": [],
+ "prefix": "HOOKPROXY",
+ "url": "https://github.com/Nall-chan/Network"
+}
\ No newline at end of file
diff --git a/HookReverseProxy/module.php b/HookReverseProxy/module.php
index 872879f..3c3ebb9 100644
--- a/HookReverseProxy/module.php
+++ b/HookReverseProxy/module.php
@@ -1,5 +1,7 @@
GetURL($_SERVER['HOOK']);
+ if ($HookData) {
+ $URLScheme = parse_url($HookData['Url'], PHP_URL_SCHEME);
+ if (in_array($URLScheme, ['http', 'https', 'ftp'])) {
+ return $this->DeliveryRemoteFile($HookData, $_GET);
+ }
+ return $this->DeliveryLocalFile($HookData['Url'], $HookData['forceDL']);
+ } else {
+ http_response_code(404);
+ header('Content-Type: text/plain');
+ header('Connection: close');
+ header('Server: Symcon ' . IPS_GetKernelVersion());
+ header('X-Powered-By: Hook Reverse Proxy');
+ header('Expires: 0');
+ header('Cache-Control: no-cache');
+ header('Content-Type: text/plain');
+ die('File not found!');
+ }
+ }
+
private function GetURL($RequestURI)
{
$Hooks = $this->Hooks;
@@ -223,33 +252,6 @@ private function DeliveryRemoteFile(array $HookData, array $Get)
}
}
- /**
- * Interne Funktion des SDK.
- */
- protected function ProcessHookdata()
- {
- // SSL fehlt
- // Authentifizierung lokal einbauen
- $HookData = $this->GetURL($_SERVER['HOOK']);
- if ($HookData) {
- $URLScheme = parse_url($HookData['Url'], PHP_URL_SCHEME);
- if (in_array($URLScheme, ['http', 'https', 'ftp'])) {
- return $this->DeliveryRemoteFile($HookData, $_GET);
- }
- return $this->DeliveryLocalFile($HookData['Url'], $HookData['forceDL']);
- } else {
- http_response_code(404);
- header('Content-Type: text/plain');
- header('Connection: close');
- header('Server: Symcon ' . IPS_GetKernelVersion());
- header('X-Powered-By: Hook Reverse Proxy');
- header('Expires: 0');
- header('Cache-Control: no-cache');
- header('Content-Type: text/plain');
- die('File not found!');
- }
- }
-
private function unparse_url($parsed_url)
{
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
diff --git a/JSONFilter/form.json b/JSONFilter/form.json
deleted file mode 100644
index 03f71c7..0000000
--- a/JSONFilter/form.json
+++ /dev/null
@@ -1,116 +0,0 @@
-{
- "elements":
- [
- {
- "type": "Select",
- "name": "Condition",
- "caption": "Condition",
- "options": [
- {
- "caption": "and",
- "value": 0
- },
- {
- "caption": "or",
- "value": 1
- }
- ]
- }, {
- "type": "List",
- "name": "FilterItems",
- "rowCount": 20,
- "add": true,
- "delete": true,
- "sort": {
- "column": "Item",
- "direction": "ascending"
- },
- "columns": [{
- "caption": "Item",
- "name": "Item",
- "width": "auto",
- "add": "",
- "edit": {
- "type": "ValidationTextBox"
- }
- }, {
- "caption": "Value",
- "name": "Value",
- "width": "100px",
- "add": "",
- "edit": {
- "type": "ValidationTextBox"
- }
- }, {
- "caption": "Type",
- "name": "Type",
- "width": "50px",
- "add": 3,
- "edit": {
- "type": "Select",
- "caption": "Variabletyp",
- "options": [
- {
- "caption": "boolean",
- "value": 0
- },
- {
- "caption": "integer",
- "value": 1
- },
- {
- "caption": "float",
- "value": 2
- },
- {
- "caption": "string",
- "value": 3
- }
- ]
- }
- }, {
- "caption": "Condition",
- "name": "Condition",
- "width": "50px",
- "add": 0,
- "edit": {
- "type": "Select",
- "caption": "Condition",
- "options": [
- {
- "caption": "void",
- "value": 0
- },
- {
- "caption": "match",
- "value": 1
- },
- {
- "caption": "include (only string)",
- "value": 2
- }
- ]
- }
- }
- ],
- "values": []
- }, {
- "type": "Select",
- "name": "Type",
- "caption": "Filter of",
- "options": [
- {
- "caption": "Sub-Item",
- "value": 0
- },
- {
- "caption": "Self-Item",
- "value": 1
- },
- {
- "caption": "all",
- "value": 2
- }
- ]
- }]
-}
diff --git a/JSONFilter/locale.json b/JSONFilter/locale.json
deleted file mode 100644
index 0817d9b..0000000
--- a/JSONFilter/locale.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "translations": {
- "de": {
- "Host": "Host",
- "New Hub": "Neuer Hub",
- "Search Sensors": "Suche Sensoren",
- "No hubs defined!":"Keine Hubs eingerichtet!"
- }
- }
-}
\ No newline at end of file
diff --git a/JSONFilter/module.json b/JSONFilter/module.json
deleted file mode 100644
index 02c46a4..0000000
--- a/JSONFilter/module.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "id": "{57230BB1-A650-4D6A-AE7E-07B672651284}",
- "name": "JSON Filter",
- "type": 2,
- "vendor": "Nall-chan",
- "aliases": [],
- "parentRequirements": ["{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}", "{D4C1D08F-CD3B-494B-BE18-B36EF73B8F43}"],
- "childRequirements": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}"],
- "implemented": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}", "{4CB91589-CE01-4700-906F-26320EFCF6C4}", "{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}"],
- "prefix": "JSON"
-}
diff --git a/JSONFilter/module.php b/JSONFilter/module.php
deleted file mode 100644
index 31dab99..0000000
--- a/JSONFilter/module.php
+++ /dev/null
@@ -1,146 +0,0 @@
-RegisterPropertyString('FilterItems', json_encode([]));
- $this->RegisterPropertyInteger('Condition', 0);
- $this->RegisterPropertyInteger('Type', 0);
- }
-
- public function ApplyChanges()
- {
- parent::ApplyChanges();
- $Items = json_decode($this->ReadPropertyString('FilterItems'), true);
-
- if (count($Items) > 0) {
- foreach ($Items as $Item) {
- $Value = '';
- switch ($Item['Type']) {
- case 0:
- if (is_numeric($Item['Value'])) {
- $Value = (bool) $Item['Value'] ? 'true' : 'false';
- } elseif (is_string($Item['Value'])) {
- $Value = strtolower($Item['Value']) == 'true' ? 'true' : 'false';
- } else {
- $Value = 'false';
- }
- break;
- case 1:
- if (is_numeric($Item['Value'])) {
- $Value = (int) $Item['Value'] . '\D';
- } else {
- $Value = '0\D';
- }
- break;
- case 2:
- if (is_numeric($Item['Value'])) {
- $Value = (float) $Item['Value'] . '\D';
- } else {
- $Value = '0\D';
- }
- break;
- case 3:
- switch ($Item['Condition']) {
- case 0:
- $Value = '';
- break;
- case 1:
- $Value = '\\\"' . (string) $Item['Value'] . '\\\"';
-
- break;
- case 2:
- $Value = '\\\".*' . (string) $Item['Value'] . '.*\\\"';
- break;
- }
- break;
- }
- $Types[$Item['Item']][] = $Value;
- }
- foreach ($Types as $Key => $Typ) {
- if (count($Typ) > 1) {
- $ValueLine = '(' . implode('|', $Typ) . ')';
- } else {
- $ValueLine = $Typ[0];
- }
-
- if ($ValueLine != '') {
- $Lines[] = '.*\\\"' . $Key . '\\\":' . $ValueLine . '.*';
- } else {
- $Lines[] = '.*\\\"' . $Key . '\\\":.*';
- }
- }
- switch ($this->ReadPropertyInteger('Condition')) {
- case 0: // and
- $Line = implode(')(?=', $Lines);
- $Line = '.*(?=' . $Line . ').*';
- break;
- case 1: // or
- $Line = implode('|', $Lines);
- break;
- }
-
- $this->SetReceiveDataFilter($Line);
- $this->SendDebug('FILTER', $Line, 0);
- } else {
- $this->SetReceiveDataFilter('');
- $this->SendDebug('FILTER', 'NOTHING', 0);
- }
- // Alles Items lesen und als Filter setzen
- /*
- $this->SetReceiveDataFilter('.*"UUID":"' . $UUID . '".*');
- else
- $this->SetReceiveDataFilter(".*9999999999.*");
- */
- }
-
- public function ReceiveData($JSONString)
- {
- $this->SendDebug('Receive', $JSONString, 0);
- $AllData = utf8_decode(json_decode($JSONString)->Buffer);
- $this->SendDebug('Receive', $AllData, 0);
- $FilterType = $this->ReadPropertyInteger('Type');
-
- if ($FilterType == 2) {
- $this->SendDebug('ForwardToChild', $JSONString, 0);
- $this->SendDataToChildren($JSONString);
- return;
- }
-
- if ($FilterType == 0) {
- $ReceiveItems = json_decode($AllData, true);
- if ($ReceiveItems === null) {
- trigger_error('Error receive Data', E_USER_NOTICE);
- $this->SendDebug('Error', 'Error receive Data', 0);
- return;
- }
- $ReceiveItems = $this->DecodeUTF8($ReceiveItems);
- $ConfigItems = array_column(json_decode($this->ReadPropertyString('FilterItems'), true), 'Value', 'Item');
- $this->SendDebug('ConfigItems', $ConfigItems, 0);
- $Items = array_intersect_key($ReceiveItems, $ConfigItems);
- $this->SendDebug('Items', $Items, 0);
- foreach (array_keys($Items) as $Item) {
- $ReceiveItems[$Item] = $this->EncodeUTF8($ReceiveItems[$Item]);
-
- $SendData['DataID'] = '{018EF6B5-AB94-40C6-AA53-46943E824ACF}';
- $SendData['Buffer'] = json_encode($ReceiveItems[$Item]);
- $this->SendDebug('Forward', $SendData['Buffer'], 0);
- $this->SendDataToChildren(json_encode($SendData));
- }
- return;
- }
- }
-
- public function ForwardData($JSONString)
- {
- $this->SendDataToChildren($JSONString);
- }
-}
diff --git a/JSONValues/form.json b/JSONValues/form.json
deleted file mode 100644
index 815bf7a..0000000
--- a/JSONValues/form.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "elements":
- [
- {
- "type": "List",
- "name": "Items",
- "rowCount": 20,
- "add": true,
- "delete": true,
- "sort": {
- "column": "Item",
- "direction": "ascending"
- },
- "columns": [{
- "caption": "Item",
- "name": "Item",
- "width": "auto",
- "add": "",
- "edit": {
- "type": "ValidationTextBox"
- }
- }, {
- "caption": "Type",
- "name": "Type",
- "width": "150px",
- "add": 3,
- "edit": {
- "type": "Select",
- "caption": "Variabletyp",
- "options": [
- {
- "caption": "boolean",
- "value": 0
- },
- {
- "caption": "integer",
- "value": 1
- },
- {
- "caption": "float",
- "value": 2
- },
- {
- "caption": "string",
- "value": 3
- }
- ]
- }
- }
- ],
- "values": []
- }]
-}
diff --git a/JSONValues/locale.json b/JSONValues/locale.json
deleted file mode 100644
index 0615320..0000000
--- a/JSONValues/locale.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "translations": {
- "de": {
- "Instance has no active parent.": "Instanz hat keinen aktiven Parent.",
- "Error on read MiFlora data": "Fehler beim lesen der MiFlora Daten",
- "UUID": "UUID",
- "Interval": "Intervall",
- "Read data": "Lese Daten",
- "Lux": "Helligkeit",
- "BatteryLevel": "Batterie",
- "Temperature": "Temperatur",
- "Firmware": "Firmware",
- "SoilMoisture": "Bodenfeuchtigkeit",
- "SoilElectricalConductivity": "Bodenleitfähigkeit",
- "Use of min/max enables Data logging !": "Verwendung von min/max aktiviert das Logging !",
- "min Electrical Conductivity": "min Bodenleitfähigkeit",
- "max Electrical Conductivity": "max Bodenleitfähigkeit",
- "Electrical Conductivity hint": "Empfehlung Bodenleitfähigkeit",
- "fertilize": "Düngen",
- "OK": "OK",
- "over fertilize": "Überdüngt",
- "min Lux": "min Helligkeit",
- "max Lux": "max Helligkeit",
- "Lux hint": "Empfehlung Helligkeit",
- "too dark": "zu dunkel",
- "too bright": "zu hell",
- "min Moisture": "min Bodenfeuchtigkeit",
- "max Moisture": "max Bodenfeuchtigkeit",
- "Moisture hint": "Empfehlung Bodenfeuchte",
- "too dry": "zu trocken",
- "too moist": "zu feucht",
- "min Temperature": "min Temperatur",
- "max Temperature": "max Temperatur",
- "Temperature hint": "Empfehlung Temperatur",
- "too cold": "zu kalt",
- "too warm": "zu warm"
- }
- }
-}
\ No newline at end of file
diff --git a/JSONValues/module.json b/JSONValues/module.json
deleted file mode 100644
index 7d3fa87..0000000
--- a/JSONValues/module.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "id": "{2F72A5E7-B6CA-4AB4-B20E-D09EC35C7682}",
- "name": "JSON Values",
- "type": 3,
- "vendor": "Nall-chan",
- "aliases": [],
- "parentRequirements": ["{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}", "{D4C1D08F-CD3B-494B-BE18-B36EF73B8F43}"],
- "childRequirements": [],
- "implemented": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}", "{4CB91589-CE01-4700-906F-26320EFCF6C4}"],
- "prefix": "JSON"
-}
diff --git a/JSONValues/module.php b/JSONValues/module.php
deleted file mode 100644
index 414bb75..0000000
--- a/JSONValues/module.php
+++ /dev/null
@@ -1,86 +0,0 @@
-RegisterPropertyString('Items', json_encode([]));
- }
-
- public function ApplyChanges()
- {
- parent::ApplyChanges();
-
- // Alles Items lesen und als Filter setzen
- /*
- $this->SetReceiveDataFilter('.*"UUID":"' . $UUID . '".*');
- else
- $this->SetReceiveDataFilter(".*9999999999.*");
- */
-
- // Prüfen Einstellungen und anlegen Variablen
- $this->MakeStatusVariables();
- }
-
- private function MakeStatusVariables()
- {
- $Items = json_decode($this->ReadPropertyString('Items'), true);
- $this->SendDebug('Config', $Items, 0);
-// print_r($Items);
- $ConfigItems = array_column($Items, 'Type', 'Item');
-
- foreach ($ConfigItems as $Item => $Typ) {
- if ($Item == '') {
- continue;
- }
- $Ident = $this->generateIdent($Item);
- $vid = @$this->GetIDForIdent($Ident);
- if ($vid === false) {
- $this->MaintainVariable($Ident, $Item, $Typ, '', 0, true);
- $vid = $this->GetIDForIdent($Ident);
- }
- }
- }
-
- public function ReceiveData($JSONString)
- {
- $Data = utf8_decode(json_decode($JSONString)->Buffer);
- $this->SendDebug('Receive', $Data, 0);
- $ReceiveItems = json_decode($Data, true);
-
- if ($ReceiveItems === null) {
- trigger_error('Error receive Data', E_USER_NOTICE);
- return;
- }
- $ReceiveItems = $this->DecodeUTF8($ReceiveItems);
- $this->SendDebug('ReceiveItems', $ReceiveItems, 0);
- $ConfigItems = array_column(json_decode($this->ReadPropertyString('Items'), true), 'Type', 'Item');
-
- $Items = array_intersect_key($ReceiveItems, $ConfigItems);
- $this->SendDebug('ProcessItems', $Items, 0);
-
- foreach ($Items as $Item => $Value) {
- $Ident = $this->generateIdent($Item);
- $vid = @$this->GetIDForIdent($Ident);
- if ($vid === false) {
- $this->MaintainVariable($Ident, $Item, $ConfigItems[$Item], '', 0, true);
- $vid = $this->GetIDForIdent($Ident);
- }
- SetValue($vid, $Value);
- }
- }
-
- protected function generateIdent($Name)
- {
- if (preg_match('/^[a-zA-Z0-9]+$/', $Name)) {
- return $Name;
- }
- return preg_replace('/[^a-z0-9]+/i', '', $Name);
- }
-}
diff --git a/README.md b/README.md
index 217b68c..813daa0 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-[![Version](https://img.shields.io/badge/Symcon-PHPModul-red.svg)](https://www.symcon.de/service/dokumentation/entwicklerbereich/sdk-tools/sdk-php/)
+[![SDK](https://img.shields.io/badge/Symcon-PHPModul-red.svg)](https://www.symcon.de/service/dokumentation/entwicklerbereich/sdk-tools/sdk-php/)
[![Version](https://img.shields.io/badge/Modul%20Version-2.4-blue.svg)]()
[![License](https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-green.svg)](https://creativecommons.org/licenses/by-nc-sa/4.0/)
[![Version](https://img.shields.io/badge/Symcon%20Version-4.3%20%3E-green.svg)](https://www.symcon.de/forum/threads/30857-IP-Symcon-4-3-%28Stable%29-Changelog)
[![StyleCI](https://styleci.io/repos/104255893/shield?style=flat)](https://styleci.io/repos/104255893)
-# IPSNetwork
+# Network
Diese Library enthält verschiedene Module für Netzwerkanwendungen.
## Dokumentation
@@ -49,7 +49,7 @@ Diese Library enthält verschiedene Module für Netzwerkanwendungen.
**IPS 4.3:**
Bei privater Nutzung: Über das 'Module-Control' in IPS folgende URL hinzufügen.
- `git://github.com/Nall-chan/IPSNetwork.git`
+ `git://github.com/Nall-chan/Network.git`
**Bei kommerzieller Nutzung (z.B. als Errichter oder Integrator) wenden Sie sich bitte an den Autor.**
@@ -61,14 +61,14 @@ Details sind in der Dokumentation der jeweiligen Module beschrieben.
### 1. GUID der Module
-| Modul | Typ | Prefix | GUID |
+| Modul | Typ | Prefix | GUID |
| :--------------------: | :------: | :-------: | :------------------------------------: |
-| Client Splitter | Splitter | WSC | {7A107D38-75ED-47CB-83F9-F41228CAEEFA} |
-| DHCP Sniffer | Device | DHCP | {E93BCE5E-BA95-424E-8C3A-BF6AEE6CB976} |
-| Webhook Reverse Proxy | Core | HOOKPROXY | {26E5D8BC-8117-4DFB-9E85-66BB30F1CF95} |
-| WebsocketClient | Splitter | WSC | {3AB77A94-3467-4E66-8A73-840B4AD89582} |
-| WebsocketServer | Splitter | WSS | {7869923C-6E1D-4E66-A0BD-627FAD1679C2} |
-| WebSocketInterfaceTest | Splitter | WSTest | {FC11DB7C-4999-4EA7-B57A-82A878ADD273} |
+| Client Splitter | Splitter | WSC | {7A107D38-75ED-47CB-83F9-F41228CAEEFA} |
+| DHCP Sniffer | Device | DHCP | {E93BCE5E-BA95-424E-8C3A-BF6AEE6CB976} |
+| Webhook Reverse Proxy | Core | HOOKPROXY | {26E5D8BC-8117-4DFB-9E85-66BB30F1CF95} |
+| WebsocketClient | Splitter | WSC | {3AB77A94-3467-4E66-8A73-840B4AD89582} |
+| WebsocketServer | Splitter | WSS | {7869923C-6E1D-4E66-A0BD-627FAD1679C2} |
+| WebSocketInterfaceTest | Splitter | WSTest | {FC11DB7C-4999-4EA7-B57A-82A878ADD273} |
### 2. Changlog
@@ -88,7 +88,7 @@ Version 2.01:
- Doku ergänzt
Version 2.0:
- - WebSocket-Module in IPSNetwork überführt
+ - WebSocket-Module in Network überführt
Version 1.0:
- Erstes offizielles Release
@@ -97,7 +97,7 @@ Version 1.0:
Die Library ist für die nicht kommzerielle Nutzung kostenlos, Schenkungen als Unterstützung für den Autor werden hier akzeptiert:
-
+
## 6. Lizenz
diff --git a/WebSocketClient/README.md b/WebSocketClient/README.md
index abfd1be..7a6a2c3 100644
--- a/WebSocketClient/README.md
+++ b/WebSocketClient/README.md
@@ -1,4 +1,4 @@
-# WebSocket-Client (IPSNetwork)
+# WebSocket-Client (Network)
Implementierung eines Clients mit Websocket Protokoll in IPS.
@@ -30,7 +30,7 @@ Implementierung eines Clients mit Websocket Protokoll in IPS.
## 3. Installation
Über das Modul-Control folgende URL hinzufügen.
- `git://github.com/Nall-chan/IPSNetwork.git`
+ `git://github.com/Nall-chan/Network.git`
**Bei kommerzieller Nutzung (z.B. als Errichter oder Integrator) wenden Sie sich bitte an den Autor.**
@@ -112,24 +112,24 @@ bool WSC_SendPing(integer $InstanzeID, string $Text);
GUID des Moduls (z.B. wenn Instanz per PHP angelegt werden soll):
-| Instanz | GUID |
+| Instanz | GUID |
| :--------------: | :------------------------------------: |
| Websocket Client | {3AB77A94-3467-4E66-8A73-840B4AD89582} |
Eigenschaften des 'Websocket Client' für Get/SetProperty-Befehle:
-| Eigenschaft | Typ | Standardwert | Funktion |
-| :----------: | :-----: | :----------: | :-----------------------------------------------------------------------------------: |
-| Open | boolean | false | false für inaktiv, true für aktiv |
-| URL | string | | Die URL auf die sich verbunden wird |
-| Version | integer | 13 | Die WebSocket-Version 13, 8 oder 6 |
-| Origin | string | | Das Origin Feld im Protokoll |
-| PingInterval | integer | 0 | In Sekunden, wann ein Ping an den Server gesendet wird |
-| PingPayload | string | | Die im Ping zu versendenen Daten |
-| Frame | integer | 1 | Format in welchen Daten versendet werden, wenn der Typ nicht bekannt ist (2 = binär) |
-| BasisAuth | boolean | false | true = Basis-Authentifizierung verwenden |
-| Username | string | | Benutzername für die Authentifizierung |
-| Password | string | | Passwort für die Authentifizierung |
+| Eigenschaft | Typ | Standardwert | Funktion |
+| :----------: | :-----: | :----------: | :----------------------------------------------------------------------------------: |
+| Open | boolean | false | false für inaktiv, true für aktiv |
+| URL | string | | Die URL auf die sich verbunden wird |
+| Version | integer | 13 | Die WebSocket-Version 13, 8 oder 6 |
+| Origin | string | | Das Origin Feld im Protokoll |
+| PingInterval | integer | 0 | In Sekunden, wann ein Ping an den Server gesendet wird |
+| PingPayload | string | | Die im Ping zu versendenen Daten |
+| Frame | integer | 1 | Format in welchen Daten versendet werden, wenn der Typ nicht bekannt ist (2 = binär) |
+| BasisAuth | boolean | false | true = Basis-Authentifizierung verwenden |
+| Username | string | | Benutzername für die Authentifizierung |
+| Password | string | | Passwort für die Authentifizierung |
## 8. Datenaustausch
@@ -139,11 +139,11 @@ Eigenschaften des 'Websocket Client' für Get/SetProperty-Befehle:
Der WebSocket-Client buffert die Daten eigenständig bis zum nächten Paket mit gesetzten Fin-Flag.
Ping/Pong Funktionalität sowie das manuelle schließen der Verbindung sind aktuell nicht vorgesehen.
-| Parameter | Typ | Beschreibung |
-| :----------: | :-----: | :-------------------------------------------------------: |
-| DataID | string | {C51A4B94-8195-4673-B78D-04D91D52D2DD} |
-| FrameTyp | integer | 1 = text, 2 = binär |
-| Buffer | string | Payload |
+| Parameter | Typ | Beschreibung |
+| :-------: | :-----: | :------------------------------------: |
+| DataID | string | {C51A4B94-8195-4673-B78D-04D91D52D2DD} |
+| FrameTyp | integer | 1 = text, 2 = binär |
+| Buffer | string | Payload |
![](imgs/IfWSC.png)
@@ -152,12 +152,12 @@ Eigenschaften des 'Websocket Client' für Get/SetProperty-Befehle:
Es ist empfohlen nur den FrameTyp 1 & 2 in Verbindung mit Fin = true zu nutzen!
Die Instanz meldet True zurück, solange sie Verbunden ist.
-| Parameter | Typ | Beschreibung |
-| :----------: | :-----: | :-------------------------------------------------------: |
-| DataID | string | {BC49DE11-24CA-484D-85AE-9B6F24D89321} |
-| FrameTyp | integer | 0 = continuation, 1 = text, 2 = binär |
-| Fin | bool | true wenn Paket komplett, false wenn weitere Daten folgen |
-| Buffer | string | Payload |
+| Parameter | Typ | Beschreibung |
+| :-------: | :-----: | :-------------------------------------------------------: |
+| DataID | string | {BC49DE11-24CA-484D-85AE-9B6F24D89321} |
+| FrameTyp | integer | 0 = continuation, 1 = text, 2 = binär |
+| Fin | bool | true wenn Paket komplett, false wenn weitere Daten folgen |
+| Buffer | string | Payload |
![](imgs/IfWSC2.png)
@@ -166,7 +166,7 @@ Eigenschaften des 'Websocket Client' für Get/SetProperty-Befehle:
**Changlog:**
Version 1.1:
- - In IPSNetwork-Library integriert
+ - In Network-Library integriert
Version 1.0:
- Erstes offizielles Release
diff --git a/WebSocketClient/form.json b/WebSocketClient/form.json
index 30f0dac..ce4d00f 100644
--- a/WebSocketClient/form.json
+++ b/WebSocketClient/form.json
@@ -1,145 +1,143 @@
{
- "elements":
- [
- {
- "name": "Open",
- "type": "CheckBox",
- "caption": "Open"
- },
- {
- "type": "Label",
- "caption": "Use ws:// or wss:// and :port when using none HTTP-default Ports."
- },
- {
- "type": "Label",
- "caption": "Example: wss://my.host.org:9091/websocket/"
- },
- {
- "name": "URL",
- "type": "ValidationTextBox",
- "caption": "URL"
- },
- {
- "type": "Label",
- "caption": "--------------------------------------------------"
- },
- {
- "type": "Label",
- "caption": "Advanced settings:"
- },
- {
- "name": "Protocol",
- "type": "ValidationTextBox",
- "caption": "Used protocol"
- },
- {
- "name": "Version",
- "type": "Select",
- "caption": "Version",
- "options": [
- {
- "caption": "6",
- "value": 6
- },
- {
- "caption": "8",
- "value": 8
- },
- {
- "caption": "13",
- "value": 13
- }
- ]
- },
- {
- "name": "Origin",
- "type": "ValidationTextBox",
- "caption": "Send origin"
- },
- {
- "type": "Label",
- "caption": "Send Ping:"
- },
- {
- "name": "PingInterval",
- "type": "IntervalBox",
- "caption": "seconds"
- },
- {
- "name": "PingPayload",
- "type": "ValidationTextBox",
- "caption": "Ping payload"
- },
- {
- "name": "Frame",
- "type": "Select",
- "caption": "Default for SendText",
- "options": [
- {
- "caption": "text",
- "value": 1
- },
- {
- "caption": "binary",
- "value": 2
- }
- ]
- },
- {
- "type": "Label",
- "caption": "--------------------------------------------------"
- },
- {
- "type": "Label",
- "caption": "Optional HTTP Basic-Authentication:"
- },
- {
- "name": "BasisAuth",
- "type": "CheckBox",
- "caption": "Active"
- },
- {
- "name": "Username",
- "type": "ValidationTextBox",
- "caption": "Username"
- },
- {
- "name": "Password",
- "type": "PasswordTextBox",
- "caption": "Password"
+ "elements": [
+ {
+ "name": "Open",
+ "type": "CheckBox",
+ "caption": "Open"
+ },
+ {
+ "type": "Label",
+ "caption": "Use ws:// or wss:// and :port when using none HTTP-default Ports."
+ },
+ {
+ "type": "Label",
+ "caption": "Example: wss://my.host.org:9091/websocket/"
+ },
+ {
+ "name": "URL",
+ "type": "ValidationTextBox",
+ "caption": "URL"
+ },
+ {
+ "type": "Label",
+ "caption": "--------------------------------------------------"
+ },
+ {
+ "type": "Label",
+ "caption": "Advanced settings:"
+ },
+ {
+ "name": "Protocol",
+ "type": "ValidationTextBox",
+ "caption": "Used protocol"
+ },
+ {
+ "name": "Version",
+ "type": "Select",
+ "caption": "Version",
+ "options": [
+ {
+ "caption": "6",
+ "value": 6
+ },
+ {
+ "caption": "8",
+ "value": 8
+ },
+ {
+ "caption": "13",
+ "value": 13
}
- ],
- "status":
- [
- {
- "code": 102,
- "icon": "active",
- "caption": "Connected"
- },
- {
- "code": 104,
- "icon": "inactive",
- "caption": "Interface closed"
- },
- {
- "code": 201,
- "icon": "error",
- "caption": "Connection lost"
- },
- {
- "code": 202,
- "icon": "error",
- "caption": "URL invalid"
- },
- {
- "code": 203,
- "icon": "error",
- "caption": "Handshake error"
- },
- {
- "code": 204,
- "icon": "error",
- "caption": "Ping interval to small"
+ ]
+ },
+ {
+ "name": "Origin",
+ "type": "ValidationTextBox",
+ "caption": "Send origin"
+ },
+ {
+ "type": "Label",
+ "caption": "Send Ping:"
+ },
+ {
+ "name": "PingInterval",
+ "type": "IntervalBox",
+ "caption": "seconds"
+ },
+ {
+ "name": "PingPayload",
+ "type": "ValidationTextBox",
+ "caption": "Ping payload"
+ },
+ {
+ "name": "Frame",
+ "type": "Select",
+ "caption": "Default for SendText",
+ "options": [
+ {
+ "caption": "text",
+ "value": 1
+ },
+ {
+ "caption": "binary",
+ "value": 2
}
]
+ },
+ {
+ "type": "Label",
+ "caption": "--------------------------------------------------"
+ },
+ {
+ "type": "Label",
+ "caption": "Optional HTTP Basic-Authentication:"
+ },
+ {
+ "name": "BasisAuth",
+ "type": "CheckBox",
+ "caption": "Active"
+ },
+ {
+ "name": "Username",
+ "type": "ValidationTextBox",
+ "caption": "Username"
+ },
+ {
+ "name": "Password",
+ "type": "PasswordTextBox",
+ "caption": "Password"
+ }
+ ],
+ "status": [
+ {
+ "code": 102,
+ "icon": "active",
+ "caption": "Connected"
+ },
+ {
+ "code": 104,
+ "icon": "inactive",
+ "caption": "Interface closed"
+ },
+ {
+ "code": 201,
+ "icon": "error",
+ "caption": "Connection lost"
+ },
+ {
+ "code": 202,
+ "icon": "error",
+ "caption": "URL invalid"
+ },
+ {
+ "code": 203,
+ "icon": "error",
+ "caption": "Handshake error"
+ },
+ {
+ "code": 204,
+ "icon": "error",
+ "caption": "Ping interval to small"
+ }
+ ]
}
\ No newline at end of file
diff --git a/WebSocketClient/module.json b/WebSocketClient/module.json
index 99ac686..4dac8ed 100644
--- a/WebSocketClient/module.json
+++ b/WebSocketClient/module.json
@@ -3,9 +3,21 @@
"name": "WebsocketClient",
"type": 2,
"vendor": "",
- "aliases": ["Websocket Client"],
- "parentRequirements": ["{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}"],
- "childRequirements": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}","{C51A4B94-8195-4673-B78D-04D91D52D2DD}"],
- "implemented": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}", "{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}","{BC49DE11-24CA-484D-85AE-9B6F24D89321}"],
- "prefix": "WSC"
+ "aliases": [
+ "Websocket Client"
+ ],
+ "parentRequirements": [
+ "{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}"
+ ],
+ "childRequirements": [
+ "{018EF6B5-AB94-40C6-AA53-46943E824ACF}",
+ "{C51A4B94-8195-4673-B78D-04D91D52D2DD}"
+ ],
+ "implemented": [
+ "{018EF6B5-AB94-40C6-AA53-46943E824ACF}",
+ "{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}",
+ "{BC49DE11-24CA-484D-85AE-9B6F24D89321}"
+ ],
+ "prefix": "WSC",
+ "url": "https://github.com/Nall-chan/Network"
}
\ No newline at end of file
diff --git a/WebSocketClient/module.php b/WebSocketClient/module.php
index 3c7dc84..0c0b170 100644
--- a/WebSocketClient/module.php
+++ b/WebSocketClient/module.php
@@ -1,5 +1,7 @@
KernelReady();
break;
@@ -151,22 +155,6 @@ public function MessageSink($TimeStamp, $SenderID, $Message, $Data)
}
}
- /**
- * Wird ausgeführt wenn der Kernel hochgefahren wurde.
- */
- protected function KernelReady()
- {
- @$this->ApplyChanges();
- }
-
- /**
- * Wird ausgeführt wenn sich der Parent ändert.
- */
- protected function ForceRefresh()
- {
- $this->ApplyChanges();
- }
-
/**
* Interne Funktion des SDK.
*/
@@ -222,7 +210,7 @@ public function ApplyChanges()
}
$OldState = $this->State;
$this->SendDebug(__FUNCTION__, 'OldState:' . $OldState, 0);
- if ((($OldState != WebSocketState::unknow) and ( $OldState != WebSocketState::Connected)) or ( $OldState == WebSocketState::init)) {
+ if ((($OldState != WebSocketState::unknow) && ($OldState != WebSocketState::Connected)) || ($OldState == WebSocketState::init)) {
return;
}
@@ -254,7 +242,7 @@ public function ApplyChanges()
$Open = false;
trigger_error('Invalid URL', E_USER_NOTICE);
} else {
- if (($this->ReadPropertyInteger('PingInterval') != 0) and ( $this->ReadPropertyInteger('PingInterval') < 5)) {
+ if (($this->ReadPropertyInteger('PingInterval') != 0) && ($this->ReadPropertyInteger('PingInterval') < 5)) {
$NewState = IS_EBASE + 4;
$Open = false;
trigger_error('Ping interval to small', E_USER_NOTICE);
@@ -328,6 +316,241 @@ public function ApplyChanges()
$this->SetStatus($NewState);
}
+ //################# DATAPOINTS CHILDS
+ /**
+ * Interne Funktion des SDK. Nimmt Daten von Childs entgegen und sendet Diese weiter.
+ *
+ * @param string $JSONString
+ * @result bool true wenn Daten gesendet werden konnten, sonst false.
+ */
+ public function ForwardData($JSONString)
+ {
+ if ($this->State != WebSocketState::Connected) {
+ trigger_error('Not connected', E_USER_NOTICE);
+ return false;
+ }
+ $Data = json_decode($JSONString);
+ if ($Data->DataID == '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}') { //Raw weitersenden
+ $this->SendText(utf8_decode($Data->Buffer));
+ }
+ if ($Data->DataID == '{BC49DE11-24CA-484D-85AE-9B6F24D89321}') { // WSC send
+ $this->Send(utf8_decode($Data->Buffer), $Data->FrameTyp, $Data->Fin);
+ }
+ return true;
+ }
+
+ //################# DATAPOINTS PARENT
+ /**
+ * Empfängt Daten vom Parent.
+ *
+ * @param string $JSONString Das empfangene JSON-kodierte Objekt vom Parent.
+ * @result bool True wenn Daten verarbeitet wurden, sonst false.
+ */
+ public function ReceiveData($JSONString)
+ {
+ $data = json_decode($JSONString);
+ if ($this->UseTLS) { // TLS aktiv
+ $Data = $this->TLSReceiveBuffer . utf8_decode($data->Buffer);
+ if ((ord($Data[0]) >= 0x14) && (ord($Data[0]) <= 0x18) && (substr($Data, 1, 2) == "\x03\x03")) {
+ $TLSData = $Data;
+ $Data = '';
+
+ while (strlen($TLSData) > 0) {
+ $len = unpack('n', substr($TLSData, 3, 2))[1] + 5;
+ if (strlen($TLSData) >= $len) {
+ $Part = substr($TLSData, 0, $len);
+ $TLSData = substr($TLSData, $len);
+ if ($this->TLSState == TLSState::init) {
+ if (!$this->WriteTLSReceiveData($Part)) {
+ break;
+ }
+ } elseif ($this->TLSState == TLSState::Connected) {
+ $this->SendDebug('Receive TLS Frame', $Part, 0);
+ try {
+ $TLS = $this->GetTLSContext();
+ $TLS->encode($Part);
+ $Data .= $TLS->input();
+ $this->SetTLSContext($TLS);
+ } catch (\PTLS\Exceptions\TLSAlertException $e) {
+ $this->SendDebug('Error', $e->getMessage(), 0);
+ $out = $e->decode();
+ if (($out !== null) && (strlen($out) > 0)) {
+ $JSON['DataID'] = '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}';
+ $JSON['Buffer'] = utf8_encode($out);
+ $JsonString = json_encode($JSON);
+ parent::SendDataToParent($JsonString);
+ }
+ trigger_error($e->getMessage(), E_USER_NOTICE);
+ $this->TLSState = TLSState::unknow;
+ $this->TLSReceiveBuffer = '';
+ return;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ if (strlen($TLSData) == 0) {
+ $this->TLSReceiveBuffer = '';
+ } else {
+ //$this->SendDebug('Receive TLS Part', $TLSData, 0);
+ $this->TLSReceiveBuffer = $TLSData;
+ }
+ } else { // Anfang (inkl. Buffer) paßt nicht
+ $this->TLSReceiveBuffer = '';
+ return;
+ }
+ } else { // ende TLS
+ $Data = utf8_decode($data->Buffer);
+ }
+
+ $Data = $this->Buffer . $Data;
+ if ($Data == '') {
+ return;
+ }
+ switch ($this->State) {
+ case WebSocketState::HandshakeSend:
+ if (strpos($Data, "\r\n\r\n") !== false) {
+ $this->Handshake = $Data;
+ $this->State = WebSocketState::HandshakeReceived;
+ $Data = '';
+ } else {
+ $this->SendDebug('Receive inclomplete Handshake', $Data, 0);
+ }
+ $this->Buffer = $Data;
+ break;
+ case WebSocketState::Connected:
+ $this->SendDebug('ReceivePacket', $Data, 1);
+ while (true) {
+ if (strlen($Data) < 2) {
+ break;
+ }
+ $Frame = new WebSocketFrame($Data);
+ if ($Data == $Frame->Tail) {
+ break;
+ }
+ $Data = $Frame->Tail;
+ $Frame->Tail = null;
+ $this->DecodeFrame($Frame);
+ }
+ $this->Buffer = $Data;
+ break;
+ case WebSocketState::CloseSend:
+ $this->SendDebug('Receive', 'Server answer client stream close !', 0);
+ $this->State = WebSocketState::CloseReceived;
+ break;
+ }
+ }
+
+ //################# PUBLIC
+ /**
+ * Versendet RawData mit OpCode an den IO.
+ *
+ * @param string $Text
+ */
+ public function SendText(string $Text)
+ {
+ if ($this->State != WebSocketState::Connected) {
+ trigger_error('Not connected', E_USER_NOTICE);
+ return false;
+ }
+ $this->Send($Text, $this->ReadPropertyInteger('Frame'));
+ return true;
+ }
+
+ /**
+ * Versendet ein String.
+ *
+ * @param bool $Fin
+ * @param int $OPCode
+ * @param string $Text
+ */
+ public function SendPacket(bool $Fin, int $OPCode, string $Text)
+ {
+ if (($OPCode < 0) || ($OPCode > 2)) {
+ trigger_error('OpCode invalid', E_USER_NOTICE);
+ return false;
+ }
+ if ($this->State != WebSocketState::Connected) {
+ trigger_error('Not connected', E_USER_NOTICE);
+ return false;
+ }
+ $this->Send($Text, $OPCode, $Fin);
+ return true;
+ }
+
+ /**
+ * Wird durch den Timer aufgerufen und senden einen Ping an den Server.
+ */
+ public function Keepalive()
+ {
+ $result = @$this->SendPing($this->ReadPropertyString('PingPayload'));
+ if ($result !== true) {
+ $this->SetStatus(IS_EBASE + 1);
+ $this->SetTimerInterval('KeepAlive', 0);
+ trigger_error('Ping timeout', E_USER_NOTICE);
+ }
+ }
+
+ /**
+ * Versendet einen Ping an den Server.
+ *
+ * @param string $Text Der zu versendene Payload im Ping.
+ *
+ * @return bool True wenn Ping bestätigt wurde, sonst false.
+ */
+ public function SendPing(string $Text)
+ {
+ $this->Send($Text, WebSocketOPCode::ping);
+ $Result = $this->WaitForPong();
+ if ($Result === false) {
+ trigger_error('Timeout', E_USER_NOTICE);
+ return false;
+ }
+
+ if ($Result != $Text) {
+ trigger_error('Wrong pong received', E_USER_NOTICE);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Wird ausgeführt wenn der Kernel hochgefahren wurde.
+ */
+ protected function KernelReady()
+ {
+ @$this->ApplyChanges();
+ }
+
+ /**
+ * Wird ausgeführt wenn sich der Parent ändert.
+ */
+ protected function ForceRefresh()
+ {
+ $this->ApplyChanges();
+ }
+
+ /**
+ * Sendet ein Paket an den Parent.
+ *
+ * @param string $Data
+ */
+ protected function SendDataToParent($Data)
+ {
+ $JSON['DataID'] = '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}';
+ if ($this->UseTLS) {
+ $TLS = $this->GetTLSContext();
+ $this->SendDebug('Send TLS', $Data, 0);
+ $Data = $TLS->output($Data)->decode();
+ $this->SetTLSContext($TLS);
+ }
+ $JSON['Buffer'] = utf8_encode($Data);
+ $JsonString = json_encode($JSON);
+ $this->SendDebug('Send Packet', $Data, 1);
+ parent::SendDataToParent($JsonString);
+ }
+
//################# PRIVATE
/**
* Baut eine TLS Verbindung auf.
@@ -367,7 +590,7 @@ private function CreateTLSConnection()
} catch (TLSAlertException $e) {
$this->SendDebug('Error', $e->getMessage(), 1);
$out = $e->decode();
- if (($out !== null) and ( strlen($out) > 0)) {
+ if (($out !== null) && (strlen($out) > 0)) {
$JSON['DataID'] = '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}';
$JSON['Buffer'] = utf8_encode($out);
$JsonString = json_encode($JSON);
@@ -380,7 +603,7 @@ private function CreateTLSConnection()
}
$SendData = $TLS->decode();
- if (($SendData !== null) and ( strlen($SendData) > 0)) {
+ if (($SendData !== null) && (strlen($SendData) > 0)) {
$this->SendDebug('TLS loop ' . $loop, $SendData, 0);
$JSON['DataID'] = '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}';
$JSON['Buffer'] = utf8_encode($SendData);
@@ -653,29 +876,6 @@ private function WaitForPong()
return false;
}
- //################# DATAPOINTS CHILDS
- /**
- * Interne Funktion des SDK. Nimmt Daten von Childs entgegen und sendet Diese weiter.
- *
- * @param string $JSONString
- * @result bool true wenn Daten gesendet werden konnten, sonst false.
- */
- public function ForwardData($JSONString)
- {
- if ($this->State != WebSocketState::Connected) {
- trigger_error('Not connected', E_USER_NOTICE);
- return false;
- }
- $Data = json_decode($JSONString);
- if ($Data->DataID == '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}') { //Raw weitersenden
- $this->SendText(utf8_decode($Data->Buffer));
- }
- if ($Data->DataID == '{BC49DE11-24CA-484D-85AE-9B6F24D89321}') { // WSC send
- $this->Send(utf8_decode($Data->Buffer), $Data->FrameTyp, $Data->Fin);
- }
- return true;
- }
-
/**
* Sendet die Rohdaten an die Childs.
*
@@ -694,204 +894,8 @@ private function SendDataToChilds(string $RawData)
$this->SendDataToChildren($Data);
}
- //################# DATAPOINTS PARENT
- /**
- * Empfängt Daten vom Parent.
- *
- * @param string $JSONString Das empfangene JSON-kodierte Objekt vom Parent.
- * @result bool True wenn Daten verarbeitet wurden, sonst false.
- */
- public function ReceiveData($JSONString)
- {
- $data = json_decode($JSONString);
- if ($this->UseTLS) { // TLS aktiv
- $Data = $this->TLSReceiveBuffer . utf8_decode($data->Buffer);
- if ((ord($Data[0]) >= 0x14) && (ord($Data[0]) <= 0x18) && (substr($Data, 1, 2) == "\x03\x03")) {
- $TLSData = $Data;
- $Data = '';
-
- while (strlen($TLSData) > 0) {
- $len = unpack('n', substr($TLSData, 3, 2))[1] + 5;
- if (strlen($TLSData) >= $len) {
- $Part = substr($TLSData, 0, $len);
- $TLSData = substr($TLSData, $len);
- if ($this->TLSState == TLSState::init) {
- if (!$this->WriteTLSReceiveData($Part)) {
- break;
- }
- } elseif ($this->TLSState == TLSState::Connected) {
- $this->SendDebug('Receive TLS Frame', $Part, 0);
- try {
- $TLS = $this->GetTLSContext();
- $TLS->encode($Part);
- $Data .= $TLS->input();
- $this->SetTLSContext($TLS);
- } catch (\PTLS\Exceptions\TLSAlertException $e) {
- $this->SendDebug('Error', $e->getMessage(), 0);
- $out = $e->decode();
- if (($out !== null) and ( strlen($out) > 0)) {
- $JSON['DataID'] = '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}';
- $JSON['Buffer'] = utf8_encode($out);
- $JsonString = json_encode($JSON);
- parent::SendDataToParent($JsonString);
- }
- trigger_error($e->getMessage(), E_USER_NOTICE);
- $this->TLSState = TLSState::unknow;
- $this->TLSReceiveBuffer = '';
- return;
- }
- }
- } else {
- break;
- }
- }
- if (strlen($TLSData) == 0) {
- $this->TLSReceiveBuffer = '';
- } else {
- //$this->SendDebug('Receive TLS Part', $TLSData, 0);
- $this->TLSReceiveBuffer = $TLSData;
- }
- } else { // Anfang (inkl. Buffer) paßt nicht
- $this->TLSReceiveBuffer = '';
- return;
- }
- } else { // ende TLS
- $Data = utf8_decode($data->Buffer);
- }
-
- $Data = $this->Buffer . $Data;
- if ($Data == '') {
- return;
- }
- switch ($this->State) {
- case WebSocketState::HandshakeSend:
- if (strpos($Data, "\r\n\r\n") !== false) {
- $this->Handshake = $Data;
- $this->State = WebSocketState::HandshakeReceived;
- $Data = '';
- } else {
- $this->SendDebug('Receive inclomplete Handshake', $Data, 0);
- }
- $this->Buffer = $Data;
- break;
- case WebSocketState::Connected:
- $this->SendDebug('ReceivePacket', $Data, 1);
- while (true) {
- if (strlen($Data) < 2) {
- break;
- }
- $Frame = new WebSocketFrame($Data);
- if ($Data == $Frame->Tail) {
- break;
- }
- $Data = $Frame->Tail;
- $Frame->Tail = null;
- $this->DecodeFrame($Frame);
- }
- $this->Buffer = $Data;
- break;
- case WebSocketState::CloseSend:
- $this->SendDebug('Receive', 'Server answer client stream close !', 0);
- $this->State = WebSocketState::CloseReceived;
- break;
- }
- }
-
- /**
- * Sendet ein Paket an den Parent.
- *
- * @param string $Data
- */
- protected function SendDataToParent($Data)
- {
- $JSON['DataID'] = '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}';
- if ($this->UseTLS) {
- $TLS = $this->GetTLSContext();
- $this->SendDebug('Send TLS', $Data, 0);
- $Data = $TLS->output($Data)->decode();
- $this->SetTLSContext($TLS);
- }
- $JSON['Buffer'] = utf8_encode($Data);
- $JsonString = json_encode($JSON);
- $this->SendDebug('Send Packet', $Data, 1);
- parent::SendDataToParent($JsonString);
- }
-
- //################# PUBLIC
- /**
- * Versendet RawData mit OpCode an den IO.
- *
- * @param string $Text
- */
- public function SendText(string $Text)
- {
- if ($this->State != WebSocketState::Connected) {
- trigger_error('Not connected', E_USER_NOTICE);
- return false;
- }
- $this->Send($Text, $this->ReadPropertyInteger('Frame'));
- return true;
- }
-
/**
- * Versendet ein String.
*
- * @param bool $Fin
- * @param int $OPCode
- * @param string $Text
- */
- public function SendPacket(bool $Fin, int $OPCode, string $Text)
- {
- if (($OPCode < 0) || ($OPCode > 2)) {
- trigger_error('OpCode invalid', E_USER_NOTICE);
- return false;
- }
- if ($this->State != WebSocketState::Connected) {
- trigger_error('Not connected', E_USER_NOTICE);
- return false;
- }
- $this->Send($Text, $OPCode, $Fin);
- return true;
- }
-
- /**
- * Wird durch den Timer aufgerufen und senden einen Ping an den Server.
- */
- public function Keepalive()
- {
- $result = @$this->SendPing($this->ReadPropertyString('PingPayload'));
- if ($result !== true) {
- $this->SetStatus(IS_EBASE + 1);
- $this->SetTimerInterval('KeepAlive', 0);
- trigger_error('Ping timeout', E_USER_NOTICE);
- }
- }
-
- /**
- * Versendet einen Ping an den Server.
- *
- * @param string $Text Der zu versendene Payload im Ping.
- *
- * @return bool True wenn Ping bestätigt wurde, sonst false.
- */
- public function SendPing(string $Text)
- {
- $this->Send($Text, WebSocketOPCode::ping);
- $Result = $this->WaitForPong();
- if ($Result === false) {
- trigger_error('Timeout', E_USER_NOTICE);
- return false;
- }
-
- if ($Result != $Text) {
- trigger_error('Wrong pong received', E_USER_NOTICE);
- return false;
- }
- return true;
- }
-
- /**
- *
* @return \PTLS\TLSContext
*/
private function GetTLSContext()
@@ -901,7 +905,7 @@ private function GetTLSContext()
}
/**
- *
+ *
* @param \PTLS\TLSContext $TLS
*/
private function SetTLSContext($TLS)
@@ -909,7 +913,6 @@ private function SetTLSContext($TLS)
$this->Multi_TLS = $TLS;
$this->unlock('TLS');
}
-
}
/* @} */
diff --git a/WebSocketServer/README.md b/WebSocketServer/README.md
index 1535868..9c0ffb5 100644
--- a/WebSocketServer/README.md
+++ b/WebSocketServer/README.md
@@ -1,4 +1,4 @@
-# WebSocket-Server (IPSNetwork)
+# WebSocket-Server (Network)
Implementierung eines Server mit Websocket Protokoll in IPS.
@@ -29,7 +29,7 @@ Implementierung eines Server mit Websocket Protokoll in IPS.
## 3. Installation
Über das Modul-Control folgende URL hinzufügen.
- `git://github.com/Nall-chan/IPSNetwork.git`
+ `git://github.com/Nall-chan/Network.git`
**Bei kommerzieller Nutzung (z.B. als Errichter oder Integrator) wenden Sie sich bitte an den Autor.**
@@ -97,26 +97,26 @@ bool WSS_SendPing(integer $InstanzeID, string $ClientIP, int $ClientPort, string
GUID des Moduls (z.B. wenn Instanz per PHP angelegt werden soll):
-| Instanz | GUID |
+| Instanz | GUID |
| :--------------: | :------------------------------------: |
| Websocket Server | {7869923C-6E1D-4E66-A0BD-627FAD1679C2} |
Eigenschaften des 'Websocket Server' für Get/SetProperty-Befehle:
-| Eigenschaft | Typ | Standardwert | Funktion |
-| :----------: | :-----: | :----------: | :---------------------------------------------------------------------------: |
-| Open | boolean | false | false für inaktiv, true für aktiv |
-| Port | integer | 8080 | Port auf welchen der Server Verbindungen annimmt |
-| URI | string | / | URI auf welche Clients sich verbinden dürfen |
-| Interval | integer | 0 | Timeout & Ping-Intervall wenn Clients keine Daten übertragen |
-| TLS | boolean | false | True wenn Transport-Socket-Layer Verbindungen erlaubt sind |
-| Plain | boolean | true | True wenn unverschlüsselte Verbindungen erlaubt sind |
-| CertFile | string | siehe * | Pfad zum Zertifikat (IPS4.1) / Zertifikat base64 encodiert (IPS4.2>) |
-| KeyFile | string | siehe * | Pfad zum privaten Schlüssel (IPS4.1) / Schlüssel base64 encodiert (IPS4.2>) |
-| KeyPassword | string | siehe * | Passwort vom privaten Schlüssel |
-| BasisAuth | boolean | false | true = Basis-Authentifizierung verwenden |
-| Username | string | | Benutzername für die Authentifizierung |
-| Password | string | | Passwort für die Authentifizierung |
+| Eigenschaft | Typ | Standardwert | Funktion |
+| :---------: | :-----: | :----------: | :-------------------------------------------------------------------------: |
+| Open | boolean | false | false für inaktiv, true für aktiv |
+| Port | integer | 8080 | Port auf welchen der Server Verbindungen annimmt |
+| URI | string | / | URI auf welche Clients sich verbinden dürfen |
+| Interval | integer | 0 | Timeout & Ping-Intervall wenn Clients keine Daten übertragen |
+| TLS | boolean | false | True wenn Transport-Socket-Layer Verbindungen erlaubt sind |
+| Plain | boolean | true | True wenn unverschlüsselte Verbindungen erlaubt sind |
+| CertFile | string | siehe * | Pfad zum Zertifikat (IPS4.1) / Zertifikat base64 encodiert (IPS4.2>) |
+| KeyFile | string | siehe * | Pfad zum privaten Schlüssel (IPS4.1) / Schlüssel base64 encodiert (IPS4.2>) |
+| KeyPassword | string | siehe * | Passwort vom privaten Schlüssel |
+| BasisAuth | boolean | false | true = Basis-Authentifizierung verwenden |
+| Username | string | | Benutzername für die Authentifizierung |
+| Password | string | | Passwort für die Authentifizierung |
\* Sobald TLS auf True gesetzt wird und kein Zertifikat vorliegt, wird ein selbst-signiertes Zertifikat erzeugt und in der Instanz eingetragen.
Es ist jederzeit möglich das Zertifikat durch ein eigenes zu erstzen.
@@ -129,57 +129,57 @@ Eigenschaften des 'Websocket Server' für Get/SetProperty-Befehle:
Die Datensätze werden erst nach dem Empfang eines Fin als ein Block weitergeleitet.
Der WebSocket-Server buffert die Daten eigenständig bis zum nächten Paket mit gesetzten Fin-Flag.
-| Parameter | Typ | Beschreibung |
-| :----------: | :-----: | :-------------------------------------------------------------: |
-| DataID | string | {8F1F6C32-B1AD-4B7F-8DFB-1244A96FCACF} |
-| ClientIP | string | Die IP-Adresse des Client von welchem die Daten kommen |
-| ClientPort | string | Die Port des Client von welchem die Daten kommen |
-| FrameTyp | integer | 0 = neu verbunden, 1 = text, 2 = binär, 8 = getrennt, 10 = pong |
-| Buffer | string | Payload, nur bei FrameTyp 1, 2 und 9 |
+| Parameter | Typ | Beschreibung |
+| :--------: | :-----: | :-------------------------------------------------------------: |
+| DataID | string | {8F1F6C32-B1AD-4B7F-8DFB-1244A96FCACF} |
+| ClientIP | string | Die IP-Adresse des Client von welchem die Daten kommen |
+| ClientPort | string | Die Port des Client von welchem die Daten kommen |
+| FrameTyp | integer | 0 = neu verbunden, 1 = text, 2 = binär, 8 = getrennt, 10 = pong |
+| Buffer | string | Payload, nur bei FrameTyp 1, 2 und 9 |
![](imgs/IfWSS.png)
Folgende GUID ist komplatible mit dem ServerSocket und kann ebenfalls zum empfang genutzt werden.
-| Parameter | Typ | Beschreibung |
-| :----------: | :-----: | :-------------------------------------------------------------: |
-| DataID | string | {7A1272A4-CBDB-46EF-BFC6-DCF4A53D2FC7} |
-| ClientIP | string | Die IP-Adresse des Client zu welchem die Daten versendet werden |
-| ClientPort | string | Die Port des Client zu welchem die Daten versendet werden |
-| Type | integer | 0 = Daten, 1 = neu verbunden, 2 = getrennt |
-| Buffer | string | Payload, nur wenn Type = 0 ist |
+| Parameter | Typ | Beschreibung |
+| :--------: | :-----: | :-------------------------------------------------------------: |
+| DataID | string | {7A1272A4-CBDB-46EF-BFC6-DCF4A53D2FC7} |
+| ClientIP | string | Die IP-Adresse des Client zu welchem die Daten versendet werden |
+| ClientPort | string | Die Port des Client zu welchem die Daten versendet werden |
+| Type | integer | 0 = Daten, 1 = neu verbunden, 2 = getrennt |
+| Buffer | string | Payload, nur wenn Type = 0 ist |
**Datenversand:**
Von der untergeordneten Instanz zum WebSocket-Server (SendDataToParent im fremden Modul).
Es wird true zurückgeliefert wenn die Funktion gemäß FrameTyp erfolgreich ausgeführt wurde.
-| Parameter | Typ | Beschreibung |
-| :----------: | :-----: | :-------------------------------------------------------------: |
-| DataID | string | {714B71FB-3D11-41D1-AFAC-E06F1E983E09} |
-| ClientIP | string | Die IP-Adresse des Client zu welchem die Daten versendet werden |
-| ClientPort | string | Die Port des Client von welchem die Daten kommen |
-| FrameTyp | integer | 0 = continuation, 1 = text, 2 = binär, 8 = close, 9 = ping |
-| Fin | bool | true wenn Paket komplett, false wenn weitere Daten folgen |
-| Buffer | string | Payload, außer bei FrameTyp 8, dann leer |
+| Parameter | Typ | Beschreibung |
+| :--------: | :-----: | :-------------------------------------------------------------: |
+| DataID | string | {714B71FB-3D11-41D1-AFAC-E06F1E983E09} |
+| ClientIP | string | Die IP-Adresse des Client zu welchem die Daten versendet werden |
+| ClientPort | string | Die Port des Client von welchem die Daten kommen |
+| FrameTyp | integer | 0 = continuation, 1 = text, 2 = binär, 8 = close, 9 = ping |
+| Fin | bool | true wenn Paket komplett, false wenn weitere Daten folgen |
+| Buffer | string | Payload, außer bei FrameTyp 8, dann leer |
![](imgs/IfWSS2.png)
Folgende GUID ist komplatible mit dem ServerSocket und kann ebenfalls zum senden genutzt werden.
-| Parameter | Typ | Beschreibung |
-| :----------: | :-----: | :-------------------------------------------------------------: |
-| DataID | string | {C8792760-65CF-4C53-B5C7-A30FCC84FEFE} |
-| ClientIP | string | Die IP-Adresse des Client zu welchem die Daten versendet werden |
-| ClientPort | string | Die Port des Client zu welchem die Daten versendet werden |
-| Type | integer | 0 = Daten, 2 = Verbindung soll getrennt werden |
-| Buffer | string | Payload, außer bei Type 2, dann leer |
+| Parameter | Typ | Beschreibung |
+| :--------: | :-----: | :-------------------------------------------------------------: |
+| DataID | string | {C8792760-65CF-4C53-B5C7-A30FCC84FEFE} |
+| ClientIP | string | Die IP-Adresse des Client zu welchem die Daten versendet werden |
+| ClientPort | string | Die Port des Client zu welchem die Daten versendet werden |
+| Type | integer | 0 = Daten, 2 = Verbindung soll getrennt werden |
+| Buffer | string | Payload, außer bei Type 2, dann leer |
Mit folgender GUID (Virtual-IO) wird der Payload immer an alle verbundenen Clients versenden.
-| Parameter | Typ | Beschreibung |
-| :----------: | :-----: | :-------------------------------------------------------------: |
-| DataID | string | {79827379-F36E-4ADA-8A95-5F8D1DC92FA9} |
-| Buffer | string | Payload |
+| Parameter | Typ | Beschreibung |
+| :-------: | :----: | :------------------------------------: |
+| DataID | string | {79827379-F36E-4ADA-8A95-5F8D1DC92FA9} |
+| Buffer | string | Payload |
## 9. Anhang
@@ -198,7 +198,7 @@ Version 1.2:
- Mehrfache Verbindungen von einer IP sind nun möglich
Version 1.1:
- - In IPSNetwork-Library integriert
+ - In Network-Library integriert
Version 1.0:
- Erstes offizielles Release
diff --git a/WebSocketServer/form.json b/WebSocketServer/form.json
index 3b667a9..7a30999 100644
--- a/WebSocketServer/form.json
+++ b/WebSocketServer/form.json
@@ -1,141 +1,149 @@
{
- "elements":
- [{
- "type": "Label",
- "caption": "Caution: Only use TLS with authentication if the port is accessible externally!"
- }, {
- "name": "Open",
- "type": "CheckBox",
- "caption": "Active"
- },
- {
- "name": "Port",
- "type": "NumberSpinner",
- "caption": "Port"
- },
+ "elements": [
+ {
+ "type": "Label",
+ "caption": "Caution: Only use TLS with authentication if the port is accessible externally!"
+ },
+ {
+ "name": "Open",
+ "type": "CheckBox",
+ "caption": "Active"
+ },
+ {
+ "name": "Port",
+ "type": "NumberSpinner",
+ "caption": "Port"
+ },
+ {
+ "name": "URI",
+ "type": "ValidationTextBox",
+ "caption": "URI"
+ },
+ {
+ "name": "Interval",
+ "type": "NumberSpinner",
+ "caption": "Timeout"
+ },
+ {
+ "type": "Select",
+ "name": "Mode",
+ "caption": "Mode",
+ "options": [
{
- "name": "URI",
- "type": "ValidationTextBox",
- "caption": "URI"
- }, {
- "name": "Interval",
- "type": "NumberSpinner",
- "caption": "Timeout"
- }, {
- "type": "Select",
- "name": "Mode",
- "caption": "Mode",
- "options": [
- {
- "caption": "no TLS",
- "value": [
- {
- "name": "TLS",
- "value": false
- },
- {
- "name": "Plain",
- "value": true
- }
- ]
- },
+ "caption": "no TLS",
+ "value": [
{
- "caption": "both",
- "value": [
- {
- "name": "TLS",
- "value": true
- },
- {
- "name": "Plain",
- "value": true
- }
- ]
+ "name": "TLS",
+ "value": false
},
{
- "caption": "only TLS",
- "value": [
- {
- "name": "TLS",
- "value": true
- },
- {
- "name": "Plain",
- "value": false
- }
- ]
+ "name": "Plain",
+ "value": true
}
]
- }, {
- "type": "Label",
- "caption": "--------------------------------------------------"
- }, {
- "type": "Label",
- "caption": "Optional Certificate:"
- }, {
- "name": "CertFile",
- "type": "SelectFile",
- "extensions": ".pem,.crt,.cer",
- "caption": "Certificate"
- }, {
- "name": "KeyFile",
- "type": "SelectFile",
- "extensions": ".pem,.key",
- "caption": "Private key"
- },
- {
- "name": "KeyPassword",
- "type": "PasswordTextBox",
- "caption": "Passphrase(optional)"
- }, {
- "type": "Label",
- "caption": "--------------------------------------------------"
- }, {
- "type": "Label",
- "caption": "Optional HTTP Basic-Authentication:"
- },
- {
- "name": "BasisAuth",
- "type": "CheckBox",
- "caption": "Active"
- },
- {
- "name": "Username",
- "type": "ValidationTextBox",
- "caption": "Username"
- },
- {
- "name": "Password",
- "type": "PasswordTextBox",
- "caption": "Password"
- }
- ],
- "status":
- [
- {
- "code": 102,
- "icon": "active",
- "caption": "Interface open"
},
{
- "code": 104,
- "icon": "inactive",
- "caption": "Interface closed"
- },
- {
- "code": 201,
- "icon": "error",
- "caption": "Certificate or key missing or not found"
- },
- {
- "code": 202,
- "icon": "error",
- "caption": "Port invalid"
+ "caption": "both",
+ "value": [
+ {
+ "name": "TLS",
+ "value": true
+ },
+ {
+ "name": "Plain",
+ "value": true
+ }
+ ]
},
{
- "code": 204,
- "icon": "error",
- "caption": "Ping interval to small"
+ "caption": "only TLS",
+ "value": [
+ {
+ "name": "TLS",
+ "value": true
+ },
+ {
+ "name": "Plain",
+ "value": false
+ }
+ ]
}
]
+ },
+ {
+ "type": "Label",
+ "caption": "--------------------------------------------------"
+ },
+ {
+ "type": "Label",
+ "caption": "Optional Certificate:"
+ },
+ {
+ "name": "CertFile",
+ "type": "SelectFile",
+ "extensions": ".pem,.crt,.cer",
+ "caption": "Certificate"
+ },
+ {
+ "name": "KeyFile",
+ "type": "SelectFile",
+ "extensions": ".pem,.key",
+ "caption": "Private key"
+ },
+ {
+ "name": "KeyPassword",
+ "type": "PasswordTextBox",
+ "caption": "Passphrase(optional)"
+ },
+ {
+ "type": "Label",
+ "caption": "--------------------------------------------------"
+ },
+ {
+ "type": "Label",
+ "caption": "Optional HTTP Basic-Authentication:"
+ },
+ {
+ "name": "BasisAuth",
+ "type": "CheckBox",
+ "caption": "Active"
+ },
+ {
+ "name": "Username",
+ "type": "ValidationTextBox",
+ "caption": "Username"
+ },
+ {
+ "name": "Password",
+ "type": "PasswordTextBox",
+ "caption": "Password"
+ }
+ ],
+ "status": [
+ {
+ "code": 102,
+ "icon": "active",
+ "caption": "Interface open"
+ },
+ {
+ "code": 104,
+ "icon": "inactive",
+ "caption": "Interface closed"
+ },
+ {
+ "code": 201,
+ "icon": "error",
+ "caption": "Certificate or key missing or not found"
+ },
+ {
+ "code": 202,
+ "icon": "error",
+ "caption": "Port invalid"
+ },
+ {
+ "code": 204,
+ "icon": "error",
+ "caption": "Ping interval to small"
+ }
+ ]
}
\ No newline at end of file
diff --git a/WebSocketServer/locale.json b/WebSocketServer/locale.json
index 6950872..b758be4 100644
--- a/WebSocketServer/locale.json
+++ b/WebSocketServer/locale.json
@@ -5,7 +5,7 @@
"Active": "Aktiv",
"Port": "Port",
"URI": "URI",
- "Timeout": "Timeout",
+ "Timeout": "Zeitüberschreitung",
"Mode": "Modus",
"no TLS": "kein TLS",
"both": "beides",
@@ -27,7 +27,6 @@
"Unknow client": "Unbekannter Client",
"Client not connected": "Client nicht verbunden",
"FrameTyp invalid": "FrameTyp ungültig",
- "Timeout": "Zeitüberschreitung",
"Wrong pong received": "Falschen pong empfangen"
}
}
diff --git a/WebSocketServer/module.json b/WebSocketServer/module.json
index 7187b75..b458f54 100644
--- a/WebSocketServer/module.json
+++ b/WebSocketServer/module.json
@@ -3,9 +3,22 @@
"name": "WebsocketServer",
"type": 2,
"vendor": "",
- "aliases": ["Websocket Server"],
- "parentRequirements": ["{C8792760-65CF-4C53-B5C7-A30FCC84FEFE}"],
- "childRequirements": ["{7A1272A4-CBDB-46EF-BFC6-DCF4A53D2FC7}","{8F1F6C32-B1AD-4B7F-8DFB-1244A96FCACF}"],
- "implemented": ["{7A1272A4-CBDB-46EF-BFC6-DCF4A53D2FC7}", "{C8792760-65CF-4C53-B5C7-A30FCC84FEFE}","{714B71FB-3D11-41D1-AFAC-E06F1E983E09}","{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}"],
- "prefix": "WSS"
+ "aliases": [
+ "Websocket Server"
+ ],
+ "parentRequirements": [
+ "{C8792760-65CF-4C53-B5C7-A30FCC84FEFE}"
+ ],
+ "childRequirements": [
+ "{7A1272A4-CBDB-46EF-BFC6-DCF4A53D2FC7}",
+ "{8F1F6C32-B1AD-4B7F-8DFB-1244A96FCACF}"
+ ],
+ "implemented": [
+ "{7A1272A4-CBDB-46EF-BFC6-DCF4A53D2FC7}",
+ "{C8792760-65CF-4C53-B5C7-A30FCC84FEFE}",
+ "{714B71FB-3D11-41D1-AFAC-E06F1E983E09}",
+ "{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}"
+ ],
+ "prefix": "WSS",
+ "url": "https://github.com/Nall-chan/Network"
}
\ No newline at end of file
diff --git a/WebSocketServer/module.php b/WebSocketServer/module.php
index b5a33d1..37d4553 100644
--- a/WebSocketServer/module.php
+++ b/WebSocketServer/module.php
@@ -1,10 +1,11 @@
ApplyChanges();
break;
@@ -163,7 +167,7 @@ public function ApplyChanges()
$this->SetTimerInterval('KeepAlivePing', 0);
$OldParentID = $this->ParentID;
- if ($this->HasActiveParent() and ( $OldParentID > 0)) {
+ if ($this->HasActiveParent() && ($OldParentID > 0)) {
$this->DisconnectAllClients();
}
@@ -179,7 +183,7 @@ public function ApplyChanges()
if (!file_exists($basedir)) {
mkdir($basedir);
}
- if (($this->ReadPropertyString('CertFile') == '') and ( $this->ReadPropertyString('KeyFile') == '')) {
+ if (($this->ReadPropertyString('CertFile') == '') && ($this->ReadPropertyString('KeyFile') == '')) {
return $this->CreateNewCert($basedir);
}
@@ -236,12 +240,12 @@ public function ApplyChanges()
if (!$Open) {
$NewState = IS_INACTIVE;
} else {
- if (($Port < 1) or ( $Port > 65535)) {
+ if (($Port < 1) || ($Port > 65535)) {
$NewState = IS_EBASE + 2;
$Open = false;
trigger_error($this->Translate('Port invalid'), E_USER_NOTICE);
} else {
- if (($this->PingInterval != 0) and ( $this->PingInterval < 5)) {
+ if (($this->PingInterval != 0) && ($this->PingInterval < 5)) {
$this->PingInterval = 0;
$NewState = IS_EBASE + 4;
$Open = false;
@@ -277,6 +281,177 @@ public function ApplyChanges()
$this->NoNewClients = false;
}
+ //################# DATAPOINTS CHILDS
+ /**
+ * Interne Funktion des SDK. Nimmt Daten von Childs entgegen und sendet Diese weiter.
+ *
+ * @param string $JSONString
+ * @result bool true wenn Daten gesendet werden konnten, sonst false.
+ */
+ public function ForwardData($JSONString)
+ {
+ $Data = json_decode($JSONString);
+ if ($Data->DataID == '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}') {
+ $this->SendDebug('Forward Broadcast', utf8_decode($Data->Buffer), 0);
+ $Clients = $this->Multi_Clients;
+ foreach ($Clients as $Client) {
+ $Data->FrameTyp = $this->{'OpCode' . $Client->ClientIP . $Client->ClientPort};
+ $Data->Fin = true;
+ $this->Send(utf8_decode($Data->Buffer), $Data->FrameTyp, $Client, $Data->Fin);
+ }
+ return true;
+ }
+
+ $Client = $this->Multi_Clients->GetByIpPort(new Websocket_Client($Data->ClientIP, $Data->ClientPort));
+ if ($Client === false) {
+ trigger_error($this->Translate('Unknow client') . ': ' . $Data->ClientIP . ':' . $Data->ClientPort, E_USER_NOTICE);
+ return false;
+ }
+ if ($Client->State != WebSocketState::Connected) {
+ trigger_error($this->Translate('Client not connected') . ': ' . $Data->ClientIP . ':' . $Data->ClientPort, E_USER_NOTICE);
+ return false;
+ }
+ $this->SendDebug('Forward', utf8_decode($Data->Buffer), 0);
+
+ if ($Data->DataID == '{714B71FB-3D11-41D1-AFAC-E06F1E983E09}') {
+ if ($Data->FrameTyp == WebSocketOPCode::close) {
+ return $this->SendDisconnect($Client);
+ }
+ if ($Data->FrameTyp == WebSocketOPCode::ping) {
+ return $this->SendPing($Client->ClientIP, $Client->ClientPort, utf8_decode($Data->Buffer));
+ }
+ if (($Data->FrameTyp < 0) || ($Data->FrameTyp > 2)) {
+ trigger_error($this->Translate('FrameTyp invalid') . ': ' . $Data->ClientIP . ':' . $Data->ClientPort, E_USER_NOTICE);
+ return false;
+ }
+ } else { //{C8792760-65CF-4C53-B5C7-A30FCC84FEFE}
+ if (property_exists($Data, 'Type')) {
+ if ($Data->Type == 2) {
+ return $this->SendDisconnect($Client);
+ }
+ }
+ //Type fehlt
+ $Data->FrameTyp = $this->{'OpCode' . $Client->ClientIP . $Client->ClientPort};
+ $Data->Fin = true;
+ }
+
+ $this->Send(utf8_decode($Data->Buffer), $Data->FrameTyp, $Client, $Data->Fin);
+ return true;
+ }
+
+ //################# DATAPOINTS PARENT
+ /**
+ * Empfängt Daten vom Parent.
+ *
+ * @param string $JSONString Das empfangene JSON-kodierte Objekt vom Parent.
+ */
+ public function ReceiveData($JSONString)
+ {
+ $data = json_decode($JSONString);
+ unset($data->DataID);
+ //$this->SendDebug('incoming', $data, 0);
+ $Payload = utf8_decode($data->Buffer);
+ $Clients = $this->Multi_Clients;
+ $IncomingClient = new Websocket_Client($data->ClientIP, $data->ClientPort, WebSocketState::init);
+ $Client = $Clients->GetByIpPort($IncomingClient);
+ $this->SendDebug(($Client ? 'OLD' : 'NEW') . ' CLIENT', SocketType::ToString($data->Type), 0);
+ switch ($data->Type) {
+ case 0: /* Data */
+ if ($Client === false) {
+ $this->SendDebug('no Connection for Data found', $IncomingClient->ClientIP . ':' . $IncomingClient->ClientPort, 0);
+ $this->CloseConnection($IncomingClient);
+ } else {
+ $this->ProcessIncomingData($Client, $Payload);
+ $Clients->Update($Client);
+ }
+ break;
+ case 1: /* Connected */
+ if (!$this->NoNewClients) {
+ $this->SendDebug('new Connection', $IncomingClient->ClientIP . ':' . $IncomingClient->ClientPort, 0);
+ $this->ClearClientBuffer($IncomingClient);
+ $Clients->Update($IncomingClient);
+ }
+ break;
+ case 2: /* Disconnected */
+ if ($Client === false) {
+ $this->SendDebug('no Connection to disconnect found', $IncomingClient->ClientIP . ':' . $IncomingClient->ClientPort, 0);
+ } else {
+ $Clients->Remove($Client);
+ $this->ClearClientBuffer($Client);
+ }
+ break;
+ }
+ $this->Multi_Clients = $Clients;
+ $this->SetNextTimer();
+ }
+
+ //################# PUBLIC
+ /**
+ * Wird vom Timer aufgerufen.
+ * Sendet einen Ping an den Client welcher als nächstes das Timeout erreicht.
+ */
+ public function KeepAlive()
+ {
+ $this->SendDebug('KeepAlive', 'start', 0);
+ $this->SetTimerInterval('KeepAlivePing', 0);
+ $Client = true;
+
+ while ($Client) {
+ $Clients = $this->Multi_Clients;
+ $Client = $Clients->GetNextTimeout(1);
+ if ($Client === false) {
+ break;
+ }
+ if (@$this->SendPing($Client->ClientIP, $Client->ClientPort, '') === false) {
+ $this->SendDebug('TIMEOUT ' . $Client->ClientIP . ':' . $Client->ClientPort, 'Ping timeout', 0);
+ }
+ }
+ $this->SendDebug('KeepAlive', 'end', 0);
+ }
+
+ /**
+ * Versendet einen Ping an einen Client.
+ *
+ * @param string $ClientIP Die IP-Adresse des Client.
+ * @param int $ClientPort Der Port des Client.
+ * @param string $Text Der Payload des Ping.
+ *
+ * @return bool True bei Erfolg, im Fehlerfall wird eine Warnung und false ausgegeben.
+ */
+ public function SendPing(string $ClientIP, int $ClientPort, string $Text)
+ {
+ $Client = $this->Multi_Clients->GetByIpPort(new Websocket_Client($ClientIP, $ClientPort));
+ if ($Client === false) {
+ $this->SendDebug('Unknow client', $ClientIP . ':' . $ClientPort, 0);
+ trigger_error($this->Translate('Unknow client') . ': ' . $ClientIP . ':' . $ClientPort, E_USER_NOTICE);
+ return false;
+ }
+ if ($Client->State != WebSocketState::Connected) {
+ $this->SendDebug('Client not connected', $ClientIP . ':' . $ClientPort, 0);
+ trigger_error($this->Translate('Client not connected') . ': ' . $ClientIP . ':' . $ClientPort, E_USER_NOTICE);
+ return false;
+ }
+ $this->SendDebug('Send Ping' . $Client->ClientIP . ':' . $Client->ClientPort, $Text, 0);
+ $this->Send($Text, WebSocketOPCode::ping, $Client);
+ $Result = $this->WaitForPong($Client);
+ $this->{'Pong' . $Client->ClientIP . $Client->ClientPort} = '';
+ if ($Result === false) {
+ $this->SendDebug('Timeout ' . $Client->ClientIP . ':' . $Client->ClientPort, '', 0);
+ trigger_error($this->Translate('Timeout'), E_USER_NOTICE);
+ $this->RemoveOneClient($Client);
+ $this->CloseConnection($Client);
+ return false;
+ }
+ if ($Result !== $Text) {
+ $this->SendDebug('Error in Pong ' . $Client->ClientIP . ':' . $Client->ClientPort, $Result, 0);
+ trigger_error($this->Translate('Wrong pong received'), E_USER_NOTICE);
+ $this->RemoveOneClient($Client);
+ $this->SendDisconnect($Client);
+ return false;
+ }
+ return true;
+ }
+
//################# PRIVATE
/**
* Erzeugt ein selbst-signiertes Zertifikat.
@@ -521,7 +696,7 @@ private function SendHandshake(int $Code, string $Data, Websocket_Client $Client
private function MakeJSON(Websocket_Client $Client, string $Data, $UseTLS = true, int $Type = SocketType::Data)
{
if ($Type == SocketType::Data) {
- if ($UseTLS and $Client->UseTLS) {
+ if ($UseTLS && $Client->UseTLS) {
$this->SendDebug('Send TLS', $Data, 0);
try {
@@ -769,64 +944,6 @@ private function Send(string $RawData, int $OPCode, Websocket_Client $Client, $F
}
}
- //################# DATAPOINTS CHILDS
- /**
- * Interne Funktion des SDK. Nimmt Daten von Childs entgegen und sendet Diese weiter.
- *
- * @param string $JSONString
- * @result bool true wenn Daten gesendet werden konnten, sonst false.
- */
- public function ForwardData($JSONString)
- {
- $Data = json_decode($JSONString);
- if ($Data->DataID == '{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}') {
- $this->SendDebug('Forward Broadcast', utf8_decode($Data->Buffer), 0);
- $Clients = $this->Multi_Clients;
- foreach ($Clients as $Client) {
- $Data->FrameTyp = $this->{'OpCode' . $Client->ClientIP . $Client->ClientPort};
- $Data->Fin = true;
- $this->Send(utf8_decode($Data->Buffer), $Data->FrameTyp, $Client, $Data->Fin);
- }
- return true;
- }
-
- $Client = $this->Multi_Clients->GetByIpPort(new Websocket_Client($Data->ClientIP, $Data->ClientPort));
- if ($Client === false) {
- trigger_error($this->Translate('Unknow client') . ': ' . $Data->ClientIP . ':' . $Data->ClientPort, E_USER_NOTICE);
- return false;
- }
- if ($Client->State != WebSocketState::Connected) {
- trigger_error($this->Translate('Client not connected') . ': ' . $Data->ClientIP . ':' . $Data->ClientPort, E_USER_NOTICE);
- return false;
- }
- $this->SendDebug('Forward', utf8_decode($Data->Buffer), 0);
-
- if ($Data->DataID == '{714B71FB-3D11-41D1-AFAC-E06F1E983E09}') {
- if ($Data->FrameTyp == WebSocketOPCode::close) {
- return $this->SendDisconnect($Client);
- }
- if ($Data->FrameTyp == WebSocketOPCode::ping) {
- return $this->SendPing($Client->ClientIP, $Client->ClientPort, utf8_decode($Data->Buffer));
- }
- if (($Data->FrameTyp < 0) || ($Data->FrameTyp > 2)) {
- trigger_error($this->Translate('FrameTyp invalid') . ': ' . $Data->ClientIP . ':' . $Data->ClientPort, E_USER_NOTICE);
- return false;
- }
- } else { //{C8792760-65CF-4C53-B5C7-A30FCC84FEFE}
- if (property_exists($Data, 'Type')) {
- if ($Data->Type == 2) {
- return $this->SendDisconnect($Client);
- }
- }
- //Type fehlt
- $Data->FrameTyp = $this->{'OpCode' . $Client->ClientIP . $Client->ClientPort};
- $Data->Fin = true;
- }
-
- $this->Send(utf8_decode($Data->Buffer), $Data->FrameTyp, $Client, $Data->Fin);
- return true;
- }
-
/**
* Sendet die Rohdaten an die Childs.
*
@@ -880,24 +997,24 @@ private function ProcessIncomingData(Websocket_Client &$Client, string $Payload)
{
$this->SendDebug('Receive ' . $Client->ClientIP . ':' . $Client->ClientPort, $Payload, 0);
if ($Client->State == WebSocketState::init) { //new
- if ($this->UseTLS and ( (ord($Payload[0]) >= 0x14) && (ord($Payload[0]) <= 0x18) && (ord($Payload[1]) == 0x03))) { //valid header wenn TLS is active
+ if ($this->UseTLS && ((ord($Payload[0]) >= 0x14) && (ord($Payload[0]) <= 0x18) && (ord($Payload[1]) == 0x03))) { //valid header wenn TLS is active
$Client->State = WebSocketState::TLSisReceived;
$Client->UseTLS = true;
$this->{'BufferTLS' . $Client->ClientIP . $Client->ClientPort} = '';
$this->{'Buffer' . $Client->ClientIP . $Client->ClientPort} = '';
// TLS Config
$TLSconfig = \PTLS\TLSContext::getServerConfig([
- 'key_pair_files' => [
- 'cert' => [$this->CertData],
- 'key' => [$this->KeyData, $this->KeyPassword]
- ]
+ 'key_pair_files' => [
+ 'cert' => [$this->CertData],
+ 'key' => [$this->KeyData, $this->KeyPassword]
+ ]
]);
$this->SendDebug('NEW TLSContex', '', 0);
//$this->lock($Client->ClientIP . $Client->ClientPort);
$this->lock($Client->ClientIP . $Client->ClientPort);
$TLS = \PTLS\TLSContext::createTLS($TLSconfig);
}
- if ($this->UsePlain and ( preg_match("/^GET ?([^?#]*) HTTP\/1.1\r\n/", $Payload, $match))) { //valid header wenn Plain is active
+ if ($this->UsePlain && (preg_match("/^GET ?([^?#]*) HTTP\/1.1\r\n/", $Payload, $match))) { //valid header wenn Plain is active
$Client->State = WebSocketState::HandshakeReceived;
$Client->UseTLS = false;
$this->{'Buffer' . $Client->ClientIP . $Client->ClientPort} = '';
@@ -1034,120 +1151,6 @@ private function CloseConnection(Websocket_Client $Client)
$SendSocketClose = $this->MakeJSON($Client, '', false, SocketType::Disconnected);
$this->SendDataToParent($SendSocketClose);
}
-
- //################# DATAPOINTS PARENT
- /**
- * Empfängt Daten vom Parent.
- *
- * @param string $JSONString Das empfangene JSON-kodierte Objekt vom Parent.
- */
- public function ReceiveData($JSONString)
- {
- $data = json_decode($JSONString);
- unset($data->DataID);
- //$this->SendDebug('incoming', $data, 0);
- $Payload = utf8_decode($data->Buffer);
- $Clients = $this->Multi_Clients;
- $IncomingClient = new Websocket_Client($data->ClientIP, $data->ClientPort, WebSocketState::init);
- $Client = $Clients->GetByIpPort($IncomingClient);
- $this->SendDebug(($Client ? 'OLD' : 'NEW') . ' CLIENT', SocketType::ToString($data->Type), 0);
- switch ($data->Type) {
- case 0: /* Data */
- if ($Client === false) {
- $this->SendDebug('no Connection for Data found', $IncomingClient->ClientIP . ':' . $IncomingClient->ClientPort, 0);
- $this->CloseConnection($IncomingClient);
- } else {
- $this->ProcessIncomingData($Client, $Payload);
- $Clients->Update($Client);
- }
- break;
- case 1: /* Connected */
- if (!$this->NoNewClients) {
- $this->SendDebug('new Connection', $IncomingClient->ClientIP . ':' . $IncomingClient->ClientPort, 0);
- $this->ClearClientBuffer($IncomingClient);
- $Clients->Update($IncomingClient);
- }
- break;
- case 2: /* Disconnected */
- if ($Client === false) {
- $this->SendDebug('no Connection to disconnect found', $IncomingClient->ClientIP . ':' . $IncomingClient->ClientPort, 0);
- } else {
- $Clients->Remove($Client);
- $this->ClearClientBuffer($Client);
- }
- break;
- }
- $this->Multi_Clients = $Clients;
- $this->SetNextTimer();
- }
-
- //################# PUBLIC
- /**
- * Wird vom Timer aufgerufen.
- * Sendet einen Ping an den Client welcher als nächstes das Timeout erreicht.
- */
- public function KeepAlive()
- {
- $this->SendDebug('KeepAlive', 'start', 0);
- $this->SetTimerInterval('KeepAlivePing', 0);
- $Client = true;
-
- while ($Client) {
- $Clients = $this->Multi_Clients;
- $Client = $Clients->GetNextTimeout(1);
- if ($Client === false) {
- break;
- }
- if (@$this->SendPing($Client->ClientIP, $Client->ClientPort, '') === false) {
- $this->SendDebug('TIMEOUT ' . $Client->ClientIP . ':' . $Client->ClientPort, 'Ping timeout', 0);
- }
- }
- $this->SendDebug('KeepAlive', 'end', 0);
- }
-
- /**
- * Versendet einen Ping an einen Client.
- *
- * @param string $ClientIP Die IP-Adresse des Client.
- * @param int $ClientPort Der Port des Client.
- * @param string $Text Der Payload des Ping.
- *
- * @return bool True bei Erfolg, im Fehlerfall wird eine Warnung und false ausgegeben.
- */
- public function SendPing(string $ClientIP, int $ClientPort, string $Text)
- {
- $Client = $this->Multi_Clients->GetByIpPort(new Websocket_Client($ClientIP, $ClientPort));
- if ($Client === false) {
- $this->SendDebug('Unknow client', $ClientIP . ':' . $ClientPort, 0);
- trigger_error($this->Translate('Unknow client') . ': ' . $ClientIP . ':' . $ClientPort, E_USER_NOTICE);
- return false;
- }
- if ($Client->State != WebSocketState::Connected) {
- $this->SendDebug('Client not connected', $ClientIP . ':' . $ClientPort, 0);
- trigger_error($this->Translate('Client not connected') . ': ' . $ClientIP . ':' . $ClientPort, E_USER_NOTICE);
- return false;
- }
- $this->SendDebug('Send Ping' . $Client->ClientIP . ':' . $Client->ClientPort, $Text, 0);
- $this->Send($Text, WebSocketOPCode::ping, $Client);
- $Result = $this->WaitForPong($Client);
- $this->{'Pong' . $Client->ClientIP . $Client->ClientPort} = '';
- if ($Result === false) {
- $this->SendDebug('Timeout ' . $Client->ClientIP . ':' . $Client->ClientPort, '', 0);
- trigger_error($this->Translate('Timeout'), E_USER_NOTICE);
- $this->RemoveOneClient($Client);
- $this->CloseConnection($Client);
- return false;
- }
- if ($Result !== $Text) {
- $this->SendDebug('Error in Pong ' . $Client->ClientIP . ':' . $Client->ClientPort, $Result, 0);
- trigger_error($this->Translate('Wrong pong received'), E_USER_NOTICE);
- $this->RemoveOneClient($Client);
- $this->SendDisconnect($Client);
- return false;
- }
- return true;
- }
-
}
/* @} */
diff --git a/WebSocketServerIfTest/README.md b/WebSocketServerIfTest/README.md
index 23003e2..18551b6 100644
--- a/WebSocketServerIfTest/README.md
+++ b/WebSocketServerIfTest/README.md
@@ -1,4 +1,4 @@
-# WebSocketInterfaceTest (IPSNetwork)
+# WebSocketInterfaceTest (Network)
Beispiel-Modul für den Datenaustausch mit den WebSocket Modulen.
diff --git a/WebSocketServerIfTest/form.json b/WebSocketServerIfTest/form.json
index 6e1a00f..92079a0 100644
--- a/WebSocketServerIfTest/form.json
+++ b/WebSocketServerIfTest/form.json
@@ -1,5 +1,3 @@
{
- "elements":
- [
- ]
+ "elements": []
}
\ No newline at end of file
diff --git a/WebSocketServerIfTest/module.json b/WebSocketServerIfTest/module.json
index 3ca1d3d..9119dfe 100644
--- a/WebSocketServerIfTest/module.json
+++ b/WebSocketServerIfTest/module.json
@@ -3,9 +3,18 @@
"name": "WebSocketInterfaceTest",
"type": 2,
"vendor": "",
- "aliases": ["WebSocket-InterfaceTest"],
- "parentRequirements": ["{BC49DE11-24CA-484D-85AE-9B6F24D89321}","{714B71FB-3D11-41D1-AFAC-E06F1E983E09}"],
+ "aliases": [
+ "WebSocket-InterfaceTest"
+ ],
+ "parentRequirements": [
+ "{BC49DE11-24CA-484D-85AE-9B6F24D89321}",
+ "{714B71FB-3D11-41D1-AFAC-E06F1E983E09}"
+ ],
"childRequirements": [],
- "implemented": ["{C51A4B94-8195-4673-B78D-04D91D52D2DD}","{8F1F6C32-B1AD-4B7F-8DFB-1244A96FCACF}"],
- "prefix": "WSTest"
+ "implemented": [
+ "{C51A4B94-8195-4673-B78D-04D91D52D2DD}",
+ "{8F1F6C32-B1AD-4B7F-8DFB-1244A96FCACF}"
+ ],
+ "prefix": "WSTEST",
+ "url": "https://github.com/Nall-chan/Network"
}
\ No newline at end of file
diff --git a/WebSocketServerIfTest/module.php b/WebSocketServerIfTest/module.php
index 1041aac..806adac 100644
--- a/WebSocketServerIfTest/module.php
+++ b/WebSocketServerIfTest/module.php
@@ -1,5 +1,7 @@
Ohne
*/
-
-if (!defined('IPS_BASE')) {
- // --- BASE MESSAGE
- define('IPS_BASE', 10000); //Base Message
- define('IPS_KERNELSTARTED', IPS_BASE + 1); //Post Ready Message
- define('IPS_KERNELSHUTDOWN', IPS_BASE + 2); //Pre Shutdown Message, Runlevel UNINIT Follows
-}
-if (!defined('IPS_KERNELMESSAGE')) {
- // --- KERNEL
- define('IPS_KERNELMESSAGE', IPS_BASE + 100); //Kernel Message
- define('KR_CREATE', IPS_KERNELMESSAGE + 1); //Kernel is beeing created
- define('KR_INIT', IPS_KERNELMESSAGE + 2); //Kernel Components are beeing initialised, Modules loaded, Settings read
- define('KR_READY', IPS_KERNELMESSAGE + 3); //Kernel is ready and running
- define('KR_UNINIT', IPS_KERNELMESSAGE + 4); //Got Shutdown Message, unloading all stuff
- define('KR_SHUTDOWN', IPS_KERNELMESSAGE + 5); //Uninit Complete, Destroying Kernel Inteface
-}
-if (!defined('IPS_LOGMESSAGE')) {
- // --- KERNEL LOGMESSAGE
- define('IPS_LOGMESSAGE', IPS_BASE + 200); //Logmessage Message
- define('KL_MESSAGE', IPS_LOGMESSAGE + 1); //Normal Message | FG: Black | BG: White | STLYE : NONE
- define('KL_SUCCESS', IPS_LOGMESSAGE + 2); //Success Message | FG: Black | BG: Green | STYLE : NONE
- define('KL_NOTIFY', IPS_LOGMESSAGE + 3); //Notiy about Changes | FG: Black | BG: Blue | STLYE : NONE
- define('KL_WARNING', IPS_LOGMESSAGE + 4); //Warnings | FG: Black | BG: Yellow | STLYE : NONE
- define('KL_ERROR', IPS_LOGMESSAGE + 5); //Error Message | FG: Black | BG: Red | STLYE : BOLD
- define('KL_DEBUG', IPS_LOGMESSAGE + 6); //Debug Informations + Script Results | FG: Grey | BG: White | STLYE : NONE
- define('KL_CUSTOM', IPS_LOGMESSAGE + 7); //User Message | FG: Black | BG: White | STLYE : NONE
-}
-if (!defined('IPS_MODULEMESSAGE')) {
- // --- MODULE LOADER
- define('IPS_MODULEMESSAGE', IPS_BASE + 300); //ModuleLoader Message
- define('ML_LOAD', IPS_MODULEMESSAGE + 1); //Module loaded
- define('ML_UNLOAD', IPS_MODULEMESSAGE + 2); //Module unloaded
-}
-if (!defined('IPS_OBJECTMESSAGE')) {
- // --- OBJECT MANAGER
- define('IPS_OBJECTMESSAGE', IPS_BASE + 400);
- define('OM_REGISTER', IPS_OBJECTMESSAGE + 1); //Object was registered
- define('OM_UNREGISTER', IPS_OBJECTMESSAGE + 2); //Object was unregistered
- define('OM_CHANGEPARENT', IPS_OBJECTMESSAGE + 3); //Parent was Changed
- define('OM_CHANGENAME', IPS_OBJECTMESSAGE + 4); //Name was Changed
- define('OM_CHANGEINFO', IPS_OBJECTMESSAGE + 5); //Info was Changed
- define('OM_CHANGETYPE', IPS_OBJECTMESSAGE + 6); //Type was Changed
- define('OM_CHANGESUMMARY', IPS_OBJECTMESSAGE + 7); //Summary was Changed
- define('OM_CHANGEPOSITION', IPS_OBJECTMESSAGE + 8); //Position was Changed
- define('OM_CHANGEREADONLY', IPS_OBJECTMESSAGE + 9); //ReadOnly was Changed
- define('OM_CHANGEHIDDEN', IPS_OBJECTMESSAGE + 10); //Hidden was Changed
- define('OM_CHANGEICON', IPS_OBJECTMESSAGE + 11); //Icon was Changed
- define('OM_CHILDADDED', IPS_OBJECTMESSAGE + 12); //Child for Object was added
- define('OM_CHILDREMOVED', IPS_OBJECTMESSAGE + 13); //Child for Object was removed
- define('OM_CHANGEIDENT', IPS_OBJECTMESSAGE + 14); //Ident was Changed
-}
-if (!defined('IPS_INSTANCEMESSAGE')) {
- // --- INSTANCE MANAGER
- define('IPS_INSTANCEMESSAGE', IPS_BASE + 500); //Instance Manager Message
- define('IM_CREATE', IPS_INSTANCEMESSAGE + 1); //Instance created
- define('IM_DELETE', IPS_INSTANCEMESSAGE + 2); //Instance deleted
- define('IM_CONNECT', IPS_INSTANCEMESSAGE + 3); //Instance connectged
- define('IM_DISCONNECT', IPS_INSTANCEMESSAGE + 4); //Instance disconncted
- define('IM_CHANGESTATUS', IPS_INSTANCEMESSAGE + 5); //Status was Changed
- define('IM_CHANGESETTINGS', IPS_INSTANCEMESSAGE + 6); //Settings were Changed
- define('IM_CHANGESEARCH', IPS_INSTANCEMESSAGE + 7); //Searching was started/stopped
- define('IM_SEARCHUPDATE', IPS_INSTANCEMESSAGE + 8); //Searching found new results
- define('IM_SEARCHPROGRESS', IPS_INSTANCEMESSAGE + 9); //Searching progress in %
- define('IM_SEARCHCOMPLETE', IPS_INSTANCEMESSAGE + 10); //Searching is complete
-}
-if (!defined('IPS_VARIABLEMESSAGE')) {
- // --- VARIABLE MANAGER
- define('IPS_VARIABLEMESSAGE', IPS_BASE + 600); //Variable Manager Message
- define('VM_CREATE', IPS_VARIABLEMESSAGE + 1); //Variable Created
- define('VM_DELETE', IPS_VARIABLEMESSAGE + 2); //Variable Deleted
- define('VM_UPDATE', IPS_VARIABLEMESSAGE + 3); //On Variable Update
- define('VM_CHANGEPROFILENAME', IPS_VARIABLEMESSAGE + 4); //On Profile Name Change
- define('VM_CHANGEPROFILEACTION', IPS_VARIABLEMESSAGE + 5); //On Profile Action Change
-}
-if (!defined('IPS_SCRIPTMESSAGE')) {
- // --- SCRIPT MANAGER
- define('IPS_SCRIPTMESSAGE', IPS_BASE + 700); //Script Manager Message
- define('SM_CREATE', IPS_SCRIPTMESSAGE + 1); //On Script Create
- define('SM_DELETE', IPS_SCRIPTMESSAGE + 2); //On Script Delete
- define('SM_CHANGEFILE', IPS_SCRIPTMESSAGE + 3); //On Script File changed
- define('SM_BROKEN', IPS_SCRIPTMESSAGE + 4); //Script Broken Status changed
-}
-if (!defined('IPS_EVENTMESSAGE')) {
- // --- EVENT MANAGER
- define('IPS_EVENTMESSAGE', IPS_BASE + 800); //Event Scripter Message
- define('EM_CREATE', IPS_EVENTMESSAGE + 1); //On Event Create
- define('EM_DELETE', IPS_EVENTMESSAGE + 2); //On Event Delete
- define('EM_UPDATE', IPS_EVENTMESSAGE + 3);
- define('EM_CHANGEACTIVE', IPS_EVENTMESSAGE + 4);
- define('EM_CHANGELIMIT', IPS_EVENTMESSAGE + 5);
- define('EM_CHANGESCRIPT', IPS_EVENTMESSAGE + 6);
- define('EM_CHANGETRIGGER', IPS_EVENTMESSAGE + 7);
- define('EM_CHANGETRIGGERVALUE', IPS_EVENTMESSAGE + 8);
- define('EM_CHANGETRIGGEREXECUTION', IPS_EVENTMESSAGE + 9);
- define('EM_CHANGECYCLIC', IPS_EVENTMESSAGE + 10);
- define('EM_CHANGECYCLICDATEFROM', IPS_EVENTMESSAGE + 11);
- define('EM_CHANGECYCLICDATETO', IPS_EVENTMESSAGE + 12);
- define('EM_CHANGECYCLICTIMEFROM', IPS_EVENTMESSAGE + 13);
- define('EM_CHANGECYCLICTIMETO', IPS_EVENTMESSAGE + 14);
-}
-if (!defined('IPS_MEDIAMESSAGE')) {
- // --- MEDIA MANAGER
- define('IPS_MEDIAMESSAGE', IPS_BASE + 900); //Media Manager Message
- define('MM_CREATE', IPS_MEDIAMESSAGE + 1); //On Media Create
- define('MM_DELETE', IPS_MEDIAMESSAGE + 2); //On Media Delete
- define('MM_CHANGEFILE', IPS_MEDIAMESSAGE + 3); //On Media File changed
- define('MM_AVAILABLE', IPS_MEDIAMESSAGE + 4); //Media Available Status changed
- define('MM_UPDATE', IPS_MEDIAMESSAGE + 5);
-}
-if (!defined('IPS_LINKMESSAGE')) {
- // --- LINK MANAGER
- define('IPS_LINKMESSAGE', IPS_BASE + 1000); //Link Manager Message
- define('LM_CREATE', IPS_LINKMESSAGE + 1); //On Link Create
- define('LM_DELETE', IPS_LINKMESSAGE + 2); //On Link Delete
- define('LM_CHANGETARGET', IPS_LINKMESSAGE + 3); //On Link TargetID change
-}
-if (!defined('IPS_FLOWMESSAGE')) {
- // --- DATA HANDLER
- define('IPS_FLOWMESSAGE', IPS_BASE + 1100); //Data Handler Message
- define('FM_CONNECT', IPS_FLOWMESSAGE + 1); //On Instance Connect
- define('FM_DISCONNECT', IPS_FLOWMESSAGE + 2); //On Instance Disconnect
-}
-if (!defined('IPS_ENGINEMESSAGE')) {
- // --- SCRIPT ENGINE
- define('IPS_ENGINEMESSAGE', IPS_BASE + 1200); //Script Engine Message
- define('SE_UPDATE', IPS_ENGINEMESSAGE + 1); //On Library Refresh
- define('SE_EXECUTE', IPS_ENGINEMESSAGE + 2); //On Script Finished execution
- define('SE_RUNNING', IPS_ENGINEMESSAGE + 3); //On Script Started execution
-}
-if (!defined('IPS_PROFILEMESSAGE')) {
- // --- PROFILE POOL
- define('IPS_PROFILEMESSAGE', IPS_BASE + 1300);
- define('PM_CREATE', IPS_PROFILEMESSAGE + 1);
- define('PM_DELETE', IPS_PROFILEMESSAGE + 2);
- define('PM_CHANGETEXT', IPS_PROFILEMESSAGE + 3);
- define('PM_CHANGEVALUES', IPS_PROFILEMESSAGE + 4);
- define('PM_CHANGEDIGITS', IPS_PROFILEMESSAGE + 5);
- define('PM_CHANGEICON', IPS_PROFILEMESSAGE + 6);
- define('PM_ASSOCIATIONADDED', IPS_PROFILEMESSAGE + 7);
- define('PM_ASSOCIATIONREMOVED', IPS_PROFILEMESSAGE + 8);
- define('PM_ASSOCIATIONCHANGED', IPS_PROFILEMESSAGE + 9);
-}
-if (!defined('IPS_TIMERMESSAGE')) {
- // --- TIMER POOL
- define('IPS_TIMERMESSAGE', IPS_BASE + 1400); //Timer Pool Message
- define('TM_REGISTER', IPS_TIMERMESSAGE + 1);
- define('TM_UNREGISTER', IPS_TIMERMESSAGE + 2);
- define('TM_SETINTERVAL', IPS_TIMERMESSAGE + 3);
- define('TM_UPDATE', IPS_TIMERMESSAGE + 4);
- define('TM_RUNNING', IPS_TIMERMESSAGE + 5);
-}
-
-if (!defined('IS_ACTIVE')) { //Nur wenn Konstanten noch nicht bekannt sind.
- // --- STATUS CODES
- define('IS_SBASE', 100);
- define('IS_CREATING', IS_SBASE + 1); //module is being created
- define('IS_ACTIVE', IS_SBASE + 2); //module created and running
- define('IS_DELETING', IS_SBASE + 3); //module us being deleted
- define('IS_INACTIVE', IS_SBASE + 4); //module is not beeing used
-// --- ERROR CODES
- define('IS_EBASE', 200); //default errorcode
- define('IS_NOTCREATED', IS_EBASE + 1); //instance could not be created
-}
-
-if (!defined('vtBoolean')) { //Nur wenn Konstanten noch nicht bekannt sind.
- define('vtBoolean', 0);
- define('vtInteger', 1);
- define('vtFloat', 2);
- define('vtString', 3);
-}
/**
* DebugHelper ergänzt SendDebug um die Möglichkeit Array und Objekte auszugeben.
*/
@@ -301,7 +133,7 @@ protected function HasActiveParent()
}
/**
- * Biete Funktionen um Thread-Safe auf Objekte zuzugrifen.
+ * Biete Funktionen um auf Objekte Thread-Safe zuzugreifen.
*/
trait Semaphore
{
diff --git a/libs/WebhookHelper.php b/libs/WebhookHelper.php
index 46d78ff..3a3fbc1 100644
--- a/libs/WebhookHelper.php
+++ b/libs/WebhookHelper.php
@@ -1,5 +1,7 @@
= $start + $len) {
$this->Payload = substr($Frame, $start, $len);
- if ($this->Mask and ($len > 0)) {
+ if ($this->Mask && ($len > 0)) {
for ($i = 0; $i < strlen($this->Payload); $i++) {
$this->Payload[$i] = $this->Payload[$i] ^ $this->MaskKey[$i % 4];
}
@@ -263,7 +265,7 @@ public function ToFrame($Masked = false)
$len = 126;
}
$this->Mask = $Masked;
- if ($this->Mask and ($len > 0)) {
+ if ($this->Mask && ($len > 0)) {
$this->PayloadRAW = $this->Payload;
$len = $len | WebSocketMask::mask;
$this->MaskKey = openssl_random_pseudo_bytes(4);
@@ -319,14 +321,6 @@ class Websocket_Client
*/
public $UseTLS;
- /**
- * Liefert die Daten welche behalten werden müssen.
- */
- public function __sleep()
- {
- return ['ClientIP', 'ClientPort', 'State', 'Timestamp', 'UseTLS'];
- }
-
/**
* Erzeugt ein Websocket_Client-Objekt aus den übergebenden Daten.
*
@@ -343,6 +337,14 @@ public function __construct(string $ClientIP, int $ClientPort, $State = WebSocke
$this->Timestamp = 0;
$this->UseTLS = $UseTLS;
}
+
+ /**
+ * Liefert die Daten welche behalten werden müssen.
+ */
+ public function __sleep()
+ {
+ return ['ClientIP', 'ClientPort', 'State', 'Timestamp', 'UseTLS'];
+ }
}
/**
diff --git a/libs/loadTLS.php b/libs/loadTLS.php
index 77fc82d..961be93 100644
--- a/libs/loadTLS.php
+++ b/libs/loadTLS.php
@@ -1,5 +1,7 @@
validateLibrary(__DIR__ . '/..');
+ }
+ public function testValidateClientSplitter(): void
+ {
+ $this->validateModule(__DIR__ . '/../ClientSplitter');
+ }
+ public function testValidateDHCPSniffer(): void
+ {
+ $this->validateModule(__DIR__ . '/../DHCPSniffer');
+ }
+ public function testValidateHookReverseProxy(): void
+ {
+ $this->validateModule(__DIR__ . '/../HookReverseProxy');
+ }
+ public function testValidateWebSocketClient(): void
+ {
+ $this->validateModule(__DIR__ . '/../WebSocketClient');
+ }
+ public function testValidateWebSocketServer(): void
+ {
+ $this->validateModule(__DIR__ . '/../WebSocketServer');
+ }
+ public function testValidateWebSocketServerIfTest(): void
+ {
+ $this->validateModule(__DIR__ . '/../WebSocketServerIfTest');
+ }
+}
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
new file mode 100644
index 0000000..b1dadd3
--- /dev/null
+++ b/tests/phpunit.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ ../Network
+
+
+
+
+
+
diff --git a/tests/stubs b/tests/stubs
new file mode 160000
index 0000000..9ee089a
--- /dev/null
+++ b/tests/stubs
@@ -0,0 +1 @@
+Subproject commit 9ee089af18a9f19b8046b2f0672939121f4f3d42