Enhance WebSocket connection handling with improved timeout and error states
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
#### 2.2.0.0201-beta
|
||||||
|
Add UI enhancement for range selecting checkboxes
|
||||||
|
|
||||||
#### 2.2.0.0200-beta
|
#### 2.2.0.0200-beta
|
||||||
```diff
|
```diff
|
||||||
+ Major web UI redesign focused on cleaner layout, better information hierarchy, and faster daily workflows.
|
+ Major web UI redesign focused on cleaner layout, better information hierarchy, and faster daily workflows.
|
||||||
|
|||||||
@@ -701,8 +701,8 @@ nav p {
|
|||||||
|
|
||||||
#clientInfo {
|
#clientInfo {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(86px, 34%) 1fr;
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
gap: 7px 8px;
|
gap: 8px;
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
background: rgba(8, 20, 33, 0.44);
|
background: rgba(8, 20, 33, 0.44);
|
||||||
@@ -713,20 +713,33 @@ nav p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#clientInfo .tdKey {
|
#clientInfo .tdKey {
|
||||||
text-align: right;
|
display: none;
|
||||||
font-size: 9px;
|
|
||||||
letter-spacing: 0.08em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#clientInfo .tdVal {
|
#clientInfo .tdVal {
|
||||||
font-size: 11px;
|
font-size: 12px;
|
||||||
min-height: 34px;
|
min-height: 54px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 10px 9px;
|
||||||
|
background: rgba(17, 34, 53, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#clientInfo .tdVal::before {
|
||||||
|
content: attr(data-label);
|
||||||
|
color: #8bb9d7;
|
||||||
|
font-size: 9px;
|
||||||
|
letter-spacing: 0.07em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-family: "Space Grotesk", "Avenir Next", "Trebuchet MS", sans-serif;
|
||||||
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-cards {
|
.dashboard-cards {
|
||||||
grid-template-columns: repeat(2, minmax(120px, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
#content_table {
|
#content_table {
|
||||||
@@ -831,12 +844,16 @@ nav p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#clientInfo {
|
#clientInfo {
|
||||||
grid-template-columns: minmax(78px, 32%) 1fr;
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dashboard-cards {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
#content-interaction {
|
#content-interaction {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
@@ -876,3 +893,9 @@ nav p {
|
|||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 430px) {
|
||||||
|
#clientInfo {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,38 +58,38 @@
|
|||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="tdKey">xTeVe:</td>
|
<td class="tdKey">xTeVe:</td>
|
||||||
<td id="version" class="tdVal"> </td>
|
<td id="version" class="tdVal" data-label="xTeVe"> </td>
|
||||||
<td class="tdKey">OS:</td>
|
<td class="tdKey">OS:</td>
|
||||||
<td id="os" class="tdVal"> </td>
|
<td id="os" class="tdVal" data-label="OS"> </td>
|
||||||
<td class="tdKey phone">DVR IP:</td>
|
<td class="tdKey phone">DVR IP:</td>
|
||||||
<td id="DVR" class="tdVal phone"> </td>
|
<td id="DVR" class="tdVal phone" data-label="DVR IP"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="tdKey">UUID:</td>
|
<td class="tdKey">UUID:</td>
|
||||||
<td id="uuid" class="tdVal"> </td>
|
<td id="uuid" class="tdVal" data-label="UUID"> </td>
|
||||||
<td class="tdKey">Arch:</td>
|
<td class="tdKey">Arch:</td>
|
||||||
<td id="arch" class="tdVal"> </td>
|
<td id="arch" class="tdVal" data-label="Arch"> </td>
|
||||||
<td class="tdKey phone">M3U URL:</td>
|
<td class="tdKey phone">M3U URL:</td>
|
||||||
<td id="m3u-url" class="tdVal phone"> </td>
|
<td id="m3u-url" class="tdVal phone" data-label="M3U URL"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="tdKey">Available Streams:</td>
|
<td class="tdKey">Available Streams:</td>
|
||||||
<td id="streams" class="tdVal"> </td>
|
<td id="streams" class="tdVal" data-label="Available Streams"> </td>
|
||||||
<td class="tdKey">EPG Source:</td>
|
<td class="tdKey">EPG Source:</td>
|
||||||
<td id="epgSource" class="tdVal"> </td>
|
<td id="epgSource" class="tdVal" data-label="EPG Source"> </td>
|
||||||
<td class="tdKey phone">XEPG URL:</td>
|
<td class="tdKey phone">XEPG URL:</td>
|
||||||
<td id="xepg-url" class="tdVal phone"> </td>
|
<td id="xepg-url" class="tdVal phone" data-label="XEPG URL"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="tdKey">XEPG Channels:</td>
|
<td class="tdKey">XEPG Channels:</td>
|
||||||
<td id="xepg" class="tdVal"> </td>
|
<td id="xepg" class="tdVal" data-label="XEPG Channels"> </td>
|
||||||
<td class="tdKey">Errors:</td>
|
<td class="tdKey">Errors:</td>
|
||||||
<td id="errors" class="tdVal"> </td>
|
<td id="errors" class="tdVal" data-label="Errors"> </td>
|
||||||
<td class="tdKey">Warnings:</td>
|
<td class="tdKey">Warnings:</td>
|
||||||
<td id="warnings" class="tdVal"> </td>
|
<td id="warnings" class="tdVal" data-label="Warnings"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -21,9 +21,55 @@ var Server = /** @class */ (function () {
|
|||||||
this.protocol = "wss://";
|
this.protocol = "wss://";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var url = this.protocol + window.location.hostname + ":" + window.location.port + "/data/" + "?Token=" + getCookie("Token");
|
var wsHost = window.location.host;
|
||||||
|
if (wsHost == undefined || wsHost.length < 1) {
|
||||||
|
wsHost = window.location.hostname;
|
||||||
|
}
|
||||||
|
var url = this.protocol + wsHost + "/data/" + "?Token=" + getCookie("Token");
|
||||||
data["cmd"] = this.cmd;
|
data["cmd"] = this.cmd;
|
||||||
var ws = new WebSocket(url);
|
var ws = new WebSocket(url);
|
||||||
|
var isLogUpdate = data["cmd"] == "updateLog";
|
||||||
|
var responseReceived = false;
|
||||||
|
var requestFinished = false;
|
||||||
|
var timeoutMs = 12000;
|
||||||
|
var requestTimeout;
|
||||||
|
var finishRequest = function (state, responseSuccess) {
|
||||||
|
if (responseSuccess === void 0) { responseSuccess = false; }
|
||||||
|
if (requestFinished == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
requestFinished = true;
|
||||||
|
SERVER_CONNECTION = false;
|
||||||
|
window.clearTimeout(requestTimeout);
|
||||||
|
if (responseSuccess == true) {
|
||||||
|
if (state == "online") {
|
||||||
|
WS_FAILURE_COUNT = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WS_FAILURE_COUNT++;
|
||||||
|
}
|
||||||
|
if (isLogUpdate == false) {
|
||||||
|
showElement("loading", false);
|
||||||
|
}
|
||||||
|
if (state != "") {
|
||||||
|
setConnectionState(state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
requestTimeout = window.setTimeout(function () {
|
||||||
|
console.log("Websocket request timed out.");
|
||||||
|
var timeoutState = "offline";
|
||||||
|
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||||
|
timeoutState = "idle";
|
||||||
|
}
|
||||||
|
finishRequest(timeoutState, false);
|
||||||
|
try {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}, timeoutMs);
|
||||||
ws.onopen = function () {
|
ws.onopen = function () {
|
||||||
WS_AVAILABLE = true;
|
WS_AVAILABLE = true;
|
||||||
if (data["cmd"] != "updateLog") {
|
if (data["cmd"] != "updateLog") {
|
||||||
@@ -37,18 +83,18 @@ var Server = /** @class */ (function () {
|
|||||||
};
|
};
|
||||||
ws.onerror = function (e) {
|
ws.onerror = function (e) {
|
||||||
console.log("No websocket connection to xTeVe could be established. Check your network configuration.");
|
console.log("No websocket connection to xTeVe could be established. Check your network configuration.");
|
||||||
SERVER_CONNECTION = false;
|
var errorState = "offline";
|
||||||
setConnectionState("offline");
|
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||||
|
errorState = "idle";
|
||||||
|
}
|
||||||
|
finishRequest(errorState, false);
|
||||||
if (WS_AVAILABLE == false) {
|
if (WS_AVAILABLE == false) {
|
||||||
alert("No websocket connection to xTeVe could be established. Check your network configuration.");
|
alert("No websocket connection to xTeVe could be established. Check your network configuration.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ws.onmessage = function (e) {
|
ws.onmessage = function (e) {
|
||||||
SERVER_CONNECTION = false;
|
responseReceived = true;
|
||||||
showElement("loading", false);
|
finishRequest("online", true);
|
||||||
if (data["cmd"] != "updateLog") {
|
|
||||||
setConnectionState("online");
|
|
||||||
}
|
|
||||||
console.log("RESPONSE:");
|
console.log("RESPONSE:");
|
||||||
var response = JSON.parse(e.data);
|
var response = JSON.parse(e.data);
|
||||||
console.log(response);
|
console.log(response);
|
||||||
@@ -103,9 +149,20 @@ var Server = /** @class */ (function () {
|
|||||||
}
|
}
|
||||||
createLayout();
|
createLayout();
|
||||||
};
|
};
|
||||||
|
ws.onclose = function () {
|
||||||
|
if (responseReceived == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var closeState = "offline";
|
||||||
|
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||||
|
closeState = "idle";
|
||||||
|
}
|
||||||
|
finishRequest(closeState, false);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
return Server;
|
return Server;
|
||||||
}());
|
}());
|
||||||
|
var WS_FAILURE_COUNT = 0;
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
var value = "; " + document.cookie;
|
var value = "; " + document.cookie;
|
||||||
var parts = value.split("; " + name + "=");
|
var parts = value.split("; " + name + "=");
|
||||||
|
|||||||
86
src/webUI.go
86
src/webUI.go
File diff suppressed because one or more lines are too long
@@ -30,10 +30,60 @@ class Server {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = this.protocol + window.location.hostname + ":" + window.location.port + "/data/" + "?Token=" + getCookie("Token")
|
var wsHost:string = window.location.host
|
||||||
|
if (wsHost == undefined || wsHost.length < 1) {
|
||||||
|
wsHost = window.location.hostname
|
||||||
|
}
|
||||||
|
var url = this.protocol + wsHost + "/data/" + "?Token=" + getCookie("Token")
|
||||||
|
|
||||||
data["cmd"] = this.cmd
|
data["cmd"] = this.cmd
|
||||||
var ws = new WebSocket(url)
|
var ws = new WebSocket(url)
|
||||||
|
var isLogUpdate:boolean = data["cmd"] == "updateLog"
|
||||||
|
var responseReceived:boolean = false
|
||||||
|
var requestFinished:boolean = false
|
||||||
|
var timeoutMs:number = 12000
|
||||||
|
var requestTimeout:number
|
||||||
|
|
||||||
|
var finishRequest = function(state:string, responseSuccess:boolean = false):void {
|
||||||
|
if (requestFinished == true) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
requestFinished = true
|
||||||
|
SERVER_CONNECTION = false
|
||||||
|
window.clearTimeout(requestTimeout)
|
||||||
|
|
||||||
|
if (responseSuccess == true) {
|
||||||
|
if (state == "online") {
|
||||||
|
WS_FAILURE_COUNT = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
WS_FAILURE_COUNT++
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLogUpdate == false) {
|
||||||
|
showElement("loading", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != "") {
|
||||||
|
setConnectionState(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestTimeout = window.setTimeout(function() {
|
||||||
|
console.log("Websocket request timed out.")
|
||||||
|
var timeoutState:string = "offline"
|
||||||
|
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||||
|
timeoutState = "idle"
|
||||||
|
}
|
||||||
|
finishRequest(timeoutState, false)
|
||||||
|
try {
|
||||||
|
ws.close()
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}, timeoutMs)
|
||||||
|
|
||||||
ws.onopen = function() {
|
ws.onopen = function() {
|
||||||
|
|
||||||
WS_AVAILABLE = true
|
WS_AVAILABLE = true
|
||||||
@@ -54,8 +104,11 @@ class Server {
|
|||||||
ws.onerror = function(e) {
|
ws.onerror = function(e) {
|
||||||
|
|
||||||
console.log("No websocket connection to xTeVe could be established. Check your network configuration.")
|
console.log("No websocket connection to xTeVe could be established. Check your network configuration.")
|
||||||
SERVER_CONNECTION = false
|
var errorState:string = "offline"
|
||||||
setConnectionState("offline")
|
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||||
|
errorState = "idle"
|
||||||
|
}
|
||||||
|
finishRequest(errorState, false)
|
||||||
|
|
||||||
if (WS_AVAILABLE == false) {
|
if (WS_AVAILABLE == false) {
|
||||||
alert("No websocket connection to xTeVe could be established. Check your network configuration.")
|
alert("No websocket connection to xTeVe could be established. Check your network configuration.")
|
||||||
@@ -65,12 +118,8 @@ class Server {
|
|||||||
|
|
||||||
|
|
||||||
ws.onmessage = function (e) {
|
ws.onmessage = function (e) {
|
||||||
|
responseReceived = true
|
||||||
SERVER_CONNECTION = false
|
finishRequest("online", true)
|
||||||
showElement("loading", false)
|
|
||||||
if (data["cmd"] != "updateLog") {
|
|
||||||
setConnectionState("online")
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("RESPONSE:");
|
console.log("RESPONSE:");
|
||||||
var response = JSON.parse(e.data);
|
var response = JSON.parse(e.data);
|
||||||
@@ -145,10 +194,24 @@ class Server {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ws.onclose = function() {
|
||||||
|
if (responseReceived == true) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var closeState:string = "offline"
|
||||||
|
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||||
|
closeState = "idle"
|
||||||
|
}
|
||||||
|
finishRequest(closeState, false)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var WS_FAILURE_COUNT:number = 0
|
||||||
|
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
var value = "; " + document.cookie;
|
var value = "; " + document.cookie;
|
||||||
var parts = value.split("; " + name + "=");
|
var parts = value.split("; " + name + "=");
|
||||||
|
|||||||
Reference in New Issue
Block a user