Retry client connection when websocket is disconnected.
Close websocket server reference when client has disconnected.
This commit is contained in:
@@ -27,6 +27,7 @@ type socket struct {
|
|||||||
listeners map[string][]func(args ...interface{})
|
listeners map[string][]func(args ...interface{})
|
||||||
r *http.Request
|
r *http.Request
|
||||||
id string
|
id string
|
||||||
|
closed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSocket(r *http.Request, c *websocket.Conn) *socket {
|
func newSocket(r *http.Request, c *websocket.Conn) *socket {
|
||||||
@@ -46,8 +47,13 @@ func (s *socket) Request() *http.Request {
|
|||||||
return s.r
|
return s.r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *socket) Close() {
|
||||||
|
s.closed = true
|
||||||
|
s.onMessage(message{Name: "close"})
|
||||||
|
}
|
||||||
|
|
||||||
func (s *socket) process() {
|
func (s *socket) process() {
|
||||||
defer s.onMessage(message{Name: "close"})
|
defer s.Close()
|
||||||
for {
|
for {
|
||||||
mt, m, err := s.c.ReadMessage()
|
mt, m, err := s.c.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -85,6 +91,11 @@ func (s *socket) onMessage(msg message) {
|
|||||||
func (s *socket) Emit(ev string, args ...interface{}) {
|
func (s *socket) Emit(ev string, args ...interface{}) {
|
||||||
s.mx.Lock()
|
s.mx.Lock()
|
||||||
defer s.mx.Unlock()
|
defer s.mx.Unlock()
|
||||||
|
|
||||||
|
if s.closed {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
m := message{Name: ev, Args: args}
|
m := message{Name: ev, Args: args}
|
||||||
b, err := json.Marshal(m)
|
b, err := json.Marshal(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -93,6 +104,7 @@ func (s *socket) Emit(ev string, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
if err := s.c.WriteMessage(websocket.TextMessage, b); err != nil {
|
if err := s.c.WriteMessage(websocket.TextMessage, b); err != nil {
|
||||||
log.Printf("Cannot write event to websocket connection. Got: %v\n", err)
|
log.Printf("Cannot write event to websocket connection. Got: %v\n", err)
|
||||||
|
s.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
$scope.selectedInstance = null;
|
$scope.selectedInstance = null;
|
||||||
$scope.isAlive = true;
|
$scope.isAlive = true;
|
||||||
$scope.ttl = '--:--:--';
|
$scope.ttl = '--:--:--';
|
||||||
$scope.connected = true;
|
$scope.connected = false;
|
||||||
$scope.type = {windows: false};
|
$scope.type = {windows: false};
|
||||||
$scope.isInstanceBeingCreated = false;
|
$scope.isInstanceBeingCreated = false;
|
||||||
$scope.newInstanceBtnText = '+ Add new instance';
|
$scope.newInstanceBtnText = '+ Add new instance';
|
||||||
@@ -35,7 +35,6 @@
|
|||||||
$scope.isInstanceBeingDeleted = false;
|
$scope.isInstanceBeingDeleted = false;
|
||||||
$scope.uploadProgress = 0;
|
$scope.uploadProgress = 0;
|
||||||
|
|
||||||
|
|
||||||
$scope.uploadFiles = function (files, invalidFiles) {
|
$scope.uploadFiles = function (files, invalidFiles) {
|
||||||
let total = files.length;
|
let total = files.length;
|
||||||
let uploadFile = function() {
|
let uploadFile = function() {
|
||||||
@@ -190,7 +189,7 @@
|
|||||||
base += ':' + window.location.port;
|
base += ':' + window.location.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
var socket = new WebSocket(base + '/sessions/' + sessionId + '/ws/');
|
var socket = new ReconnectingWebSocket(base + '/sessions/' + sessionId + '/ws/', null, {reconnectInterval: 1000});
|
||||||
socket.listeners = {};
|
socket.listeners = {};
|
||||||
|
|
||||||
socket.on = function(name, cb) {
|
socket.on = function(name, cb) {
|
||||||
@@ -210,10 +209,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
socket.addEventListener('open', function (event) {
|
socket.addEventListener('open', function (event) {
|
||||||
console.log('open', event);
|
$scope.connected = true;
|
||||||
|
for (var i in $scope.instances) {
|
||||||
|
var instance = $scope.instances[i];
|
||||||
|
if (instance.term) {
|
||||||
|
instance.term.setOption('disableStdin', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
socket.addEventListener('close', function (event) {
|
socket.addEventListener('close', function (event) {
|
||||||
console.log('close', event);
|
$scope.connected = false;
|
||||||
|
for (var i in $scope.instances) {
|
||||||
|
var instance = $scope.instances[i];
|
||||||
|
if (instance.term) {
|
||||||
|
instance.term.setOption('disableStdin', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
socket.addEventListener('message', function (event) {
|
socket.addEventListener('message', function (event) {
|
||||||
var m = JSON.parse(event.data);
|
var m = JSON.parse(event.data);
|
||||||
@@ -290,13 +301,6 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('connect_error', function() {
|
|
||||||
$scope.connected = false;
|
|
||||||
});
|
|
||||||
socket.on('connect', function() {
|
|
||||||
$scope.connected = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.on('instance stats', function(stats) {
|
socket.on('instance stats', function(stats) {
|
||||||
$scope.idx[stats.instance].mem = stats.mem;
|
$scope.idx[stats.instance].mem = stats.mem;
|
||||||
$scope.idx[stats.instance].cpu = stats.cpu;
|
$scope.idx[stats.instance].cpu = stats.cpu;
|
||||||
|
|||||||
@@ -280,6 +280,7 @@
|
|||||||
</md-dialog-actions>
|
</md-dialog-actions>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js" integrity="sha256-A4JwlcDvqO4JXpvEtvWY1RH8JAEMu5W21wP8GUXLUNs=" crossorigin="anonymous"></script>
|
||||||
<script
|
<script
|
||||||
src="https://code.jquery.com/jquery-3.2.1.min.js"
|
src="https://code.jquery.com/jquery-3.2.1.min.js"
|
||||||
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
|
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
|
||||||
|
|||||||
Reference in New Issue
Block a user