gérer la deconnexion au websocket (ref #23)

This commit is contained in:
afornerot 2019-10-18 13:56:25 +02:00
parent b29ce57c6e
commit 33f0d05fb6
4 changed files with 318 additions and 123 deletions

View File

@ -137,6 +137,7 @@ gos_web_socket:
server: server:
port: %websocket_port% #The port the socket server will listen on port: %websocket_port% #The port the socket server will listen on
host: %websocket_host% #The host ip to bind to host: %websocket_host% #The host ip to bind to
router: router:
resources: resources:
- "@CadolesWebsocketBundle/Resources/config/topic.yml" - "@CadolesWebsocketBundle/Resources/config/topic.yml"

View File

@ -105,4 +105,47 @@ class ChatController extends Controller
$response->headers->set('Content-Type', 'application/json'); $response->headers->set('Content-Type', 'application/json');
return $response; return $response;
} }
public function listAction(Request $request) {
// S'assurer que c'est un appel ajax
if (!$request->isXmlHttpRequest()) {
return new JsonResponse(array('message' => 'Interdit'), 400);
}
$em = $this->getDoctrine()->getManager();
$id=$request->request->get('id');
$output=array();
// On récupère le groupe
$group=$em->getRepository("CadolesCoreBundle:Group")->find($id);
if(!$group) die();
// On récupere le user
$user=$this->getUser();
if(!$user) die();
// On récupère le lien usergroup
$usergroup=$em->getRepository("CadolesCoreBundle:UserGroup")->findOneBy(["group"=>$group,"user"=>$user]);
if(!$usergroup) die();
// On récupere les messages
$messages=$em->getRepository("CadolesWebsocketBundle:Message")->findBy(["group"=>$group],["submitdate"=>"DESC"],10);
foreach($messages as $message) {
$tmp=[];
$tmp["id"]=$message->getId();
$tmp["message"]=$message->getTopic();
$tmp["submitdate"]=$message->getSubmitdate();
$tmp["userid"]=$message->getUser()->getId();
$tmp["userlastname"]=$message->getUser()->getLastname();
$tmp["userfirstname"]=$message->getUser()->getFirstname();
$tmp["useravatar"]=$message->getUser()->getAvatar();
array_push($output,$tmp);
}
$response = new Response(json_encode($output));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
} }

View File

@ -4,4 +4,8 @@ cadoles_websocket_chat:
cadoles_websocket_message_see: cadoles_websocket_message_see:
path: /user/message/see path: /user/message/see
defaults: { _controller: CadolesWebsocketBundle:Chat:see } defaults: { _controller: CadolesWebsocketBundle:Chat:see }
cadoles_websocket_message_list:
path: /user/message/list
defaults: { _controller: CadolesWebsocketBundle:Chat:list }

View File

@ -115,12 +115,90 @@
{% block localexternalscript %} {% block localexternalscript %}
<script src="/{{alias}}/bundles/goswebsocket/js/vendor/autobahn.min.js"></script> <script src="/{{alias}}/bundles/goswebsocket/js/vendor/autobahn.min.js"></script>
<script src="/{{alias}}/bundles/goswebsocket/js/gos_web_socket_client.js"></script>
<script type="text/javascript" src="/{{alias}}/ckeditor/adapters/jquery.js"></script> <script type="text/javascript" src="/{{alias}}/ckeditor/adapters/jquery.js"></script>
{% endblock %} {% endblock %}
{% block localjavascript %} {% block localjavascript %}
var webSocket; {% if websocket_activate and app.user %}
var WS = (function()
{
var GosSocket = function(uri, sessionConfig){
this._uri = uri;
this._session = false;
this._listeners = {};
this.connect(sessionConfig);
};
GosSocket.prototype.connect = function (sessionConfig) {
var that = this;
ab.connect(this._uri,
//Function on connect
function(session){
that.fire({type: "socket/connect", data: session });
},
//Function on disconnect / error
function(code, reason){
that._session = false;
that.fire({type: "socket/disconnect", data: {code: code, reason: reason}});
},
sessionConfig
);
};
GosSocket.prototype.on = function(type, listener){
if (typeof this._listeners[type] == "undefined"){
this._listeners[type] = [];
}
this._listeners[type].push(listener);
};
GosSocket.prototype.fire = function(event){
if (typeof event == "string"){
event = { type: event };
}
if (!event.target){
event.target = this;
}
if (!event.type){ //falsy
throw new Error("Event object missing 'type' property.");
}
if (this._listeners[event.type] instanceof Array){
var listeners = this._listeners[event.type];
for (var i=0, len=listeners.length; i < len; i++){
listeners[i].call(this, event.data);
}
}
};
GosSocket.prototype.off = function(type, listener){
if (this._listeners[type] instanceof Array){
var listeners = this._listeners[type];
for (var i=0, len=listeners.length; i < len; i++){
if (listeners[i] === listener){
listeners.splice(i, 1);
break;
}
}
}
};
return {
connect: function(uri, sessionConfig)
{
return new GosSocket(uri, sessionConfig);
}
}
})();
{% endif %}
$(document).ready(function(){ $(document).ready(function(){
if (CKEDITOR.instances["chat_message"]) CKEDITOR.instances["chat_message"].destroy(); if (CKEDITOR.instances["chat_message"]) CKEDITOR.instances["chat_message"].destroy();
@ -153,26 +231,43 @@ var webSocket;
}); });
function websocket() {% if websocket_activate and app.user %}
{
{% if websocket_activate and app.user %} var session;
var dateoptions = {weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit" };
var timer;
var delayRetry=5000;
var isdeco=false;
var tosend=false;
var tosendmail=false;
var todelete=false;
var idtodelete;
function websocket()
{
var _WS_URI = "wss://{{ gos_web_socket_server_host }}:{{ gos_web_socket_server_port }}"; var _WS_URI = "wss://{{ gos_web_socket_server_host }}:{{ gos_web_socket_server_port }}";
webSocket = WS.connect(_WS_URI,{retryDelay: delayRetry});
console.log("INI WS");
webSocket = WS.connect(_WS_URI);
console.log("END INI WS");
var dateoptions = {weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit" }; webSocket.on("socket/connect", function (sess) {
var timer; console.log("=== CONNECT ===");
var session;
webSocket.on("socket/connect", function (session) { // Sauvegardce de la session
// Reinit du tps de tentative de reco session=sess;
$('#modalinfo').modal('hide');
clearInterval(timer);
//the callback function in "subscribe" is called everytime an event is published in that channel. //the callback function in "subscribe" is called everytime an event is published in that channel.
session.subscribe("websocket/channel/{{groupid}}", function (uri, payload) { sess.subscribe("websocket/channel/{{groupid}}", function (uri, payload) {
// Récupération lastmessage
if(isdeco) recuplastmsg();
// Si action en cours
if(tosend) sendbtn();
if(tosendmail) sendbtnmail();
if(todelete) delmessage(idtodelete);
// Il est co
isdeco=false;
if(payload.msg) { if(payload.msg) {
html ="<div id='message-"+payload.msg.id+"' class='message row'>"; html ="<div id='message-"+payload.msg.id+"' class='message row'>";
html+="<div class='msgavatar'>"; html+="<div class='msgavatar'>";
@ -203,118 +298,170 @@ var webSocket;
alert(payload.alert); alert(payload.alert);
} }
}); });
$( "#sendbtn" ).click(function() {
var data = CKEDITOR.instances["chat_message"].getData();
if($("#sendbymail").bootstrapSwitch('state')) {
CKEDITOR.instances["chat_messagemail"].setData(data);
$("#mailsuject").val("{{app.session.get('appname')}} = Notification {{ group.label }}");
$("#mailto").val("");
$("#listtoavatar").html("");
{% for user in group.users %}
{%if(user.user!=app.user)%}
$("#mailto").val($("#mailto").val()+";{{user.user.email}}");
$("#listtoavatar").append($("<img class='avatar' title='{{user.user.lastname}} {{user.user.firstname}}' data-mail='{{user.user.email}}' src='\\{{alias}}\\uploads\\avatar\\{{user.user.avatar}}'>"));
{%endif%}
{% endfor %}
$('#mymodal-sendmail').modal('show');
}
else {
if(data) {
event={mykey: "{{userkey}}", type: "add", message: data};
session.publish("websocket/channel/{{groupid}}", event);
CKEDITOR.instances["chat_message"].setData('');
/* Ne plus envoyer d'event compteur on passe par de l'ajax
event={type: "add", group:{{groupid}}};
parent.parent.counter(event);
*/
}
}
});
$( "#sendbtnmail" ).click(function() {
var data = CKEDITOR.instances["chat_messagemail"].getData();
var subject=$("#mailsuject").val();
var mailto=$("#mailto").val();
if(data&&subject&&mailto) {
event={mykey: "{{userkey}}", type: "add", message: data, mail: "true", to: mailto, subject: subject};
session.publish("websocket/channel/{{groupid}}", event);
CKEDITOR.instances["chat_message"].setData('');
/* Ne plus envoyer d'event compteur on passe par de l'ajax
event={type: "add", group:{{groupid}}};
parent.parent.counter(event);
*/
$("#sendbymail").bootstrapSwitch('state',false);
$('#mymodal-sendmail').modal('hide');
}
else alert("Sujet, corps et destinataire(s) obligatoire");
});
$(document).on('click', '.delmessage', function(){
id=$(this).data("id");
event={mykey: "{{userkey}}", type: "del", id: id};
session.publish("websocket/channel/{{groupid}}", event);
});
$(document).on('click', '#listtoavatar img', function(){
var mail = ";"+$(this).data("mail");
$("#mailto").val($("#mailto").val().replace(mail, ""));
$(this).remove();
});
}); });
webSocket.on("socket/disconnect", function(error){ webSocket.on("socket/disconnect", function(error){
laberror="Disconnected for " + error.reason + " with code " + error.code; laberror="Disconnected for " + error.reason + " with code " + error.code;
console.log("=== DISCONNECT ==="); console.log("=== DISCONNECT ===");
console.log(laberror); console.log(laberror);
isdeco=true;
if(error.code==2) {
$('#modalinfo').modal('show');
$('#modalinfotext').html("<center>Impossible de se connecter au serveur.<br>Vous avez dépassé le nombre de reconnexion maximum<br><br>Veuillez retentez d'ici quelques secondes<br><br><code>"+laberror+"</code><br><br><div id='modalinfotimer'></div><br><a class='btn btn-primary' onclick='location.reload(true);'>Forcer la tentative de reconnexion</a></center>");
clearInterval(timer);
var nbtentative=10;
timer=setInterval(function(){ $('#modalinfotimer').html((nbtentative--)+"s") }, 1000);
setTimeout(function(){ websocket(); }, 10000);
//setTimeout(function(){ location.reload(true); }, 10000);
}
if(error.code==3) {
$('#modalinfo').modal('show');
$('#modalinfotext').html("<center>Impossible de se connecter au serveur.<br>Veuillez retentez d'ici quelques secondes<br><br><code>"+laberror+"</code><br><br><div id='modalinfotimer'></div><br><a class='btn btn-primary' onclick='location.reload(true);'>Forcer la tentative de reconnexion</a></center>");
clearInterval(timer);
var nbtentative=10;
timer=setInterval(function(){ $('#modalinfotimer').html((nbtentative--)+"s") }, 1000);
setTimeout(function(){ websocket(); }, 10000);
// setTimeout(function(){ location.reload(true); }, 10000);
}
if(error.code==6 || error.code==5) {
$('#modalinfotext').html("<center>Impossible de se connecter au serveur.<br>Vous allez être reconnecté d'ici quelques secondes<br><br><code>"+laberror+"</code><br><br><div id='modalinfotimer'></div><br><a class='btn btn-primary' onclick='location.reload(true);'>Forcer la tentative de reconnexion</a></center>");
clearInterval(timer);
var nbtentative=5;
//session.unsubscribe("websocket/channel/{{groupid}}");
websocket();
/*
timer=setInterval(function(){ $('#modalinfotimer').html((nbtentative--)+"s") }, 1000);
setTimeout(function(){ websocket(); }, 10000);
*/
}
}); });
}
{% endif %} $( "#sendbtn" ).click(function() {
} sendbtn();
});
function sendbtn() {
var data = CKEDITOR.instances["chat_message"].getData();
if($("#sendbymail").bootstrapSwitch('state')) {
CKEDITOR.instances["chat_messagemail"].setData(data);
$("#mailsuject").val("{{app.session.get('appname')}} = Notification {{ group.label }}");
$("#mailto").val("");
$("#listtoavatar").html("");
{% for user in group.users %}
{%if(user.user!=app.user)%}
$("#mailto").val($("#mailto").val()+";{{user.user.email}}");
$("#listtoavatar").append($("<img class='avatar' title='{{user.user.lastname}} {{user.user.firstname}}' data-mail='{{user.user.email}}' src='\\{{alias}}\\uploads\\avatar\\{{user.user.avatar}}'>"));
{%endif%}
{% endfor %}
$('#mymodal-sendmail').modal('show');
}
else {
if(data) {
try {
// Flager que l'envoit c'est fait
tosend=false;
$("#sendbtn").html("Envoyer");
$("#sendbtn").removeClass("btn-danger");
$("#sendbtn").css('cursor','auto');
// Push envent sur le websocket
event={mykey: "{{userkey}}", type: "add", message: data};
session.publish("websocket/channel/{{groupid}}", event);
CKEDITOR.instances["chat_message"].setData('');
}
catch(error) {
// L'envoi ne s'est pas fait
console.log("Retry to send");
// On flag le fait de retenter l'envoit à la reconnexion
tosend=true;
// On signal que l'envoi est en cours sur le bouton
$("#sendbtn").html("Envoi en cours");
$("#sendbtn").addClass("btn-danger");
$("#sendbtn").css('cursor','progress');
}
}
}
}
$( "#sendbtnmail" ).click(function() {
sendbtnmail();
});
function sendbtnmail() {
var data = CKEDITOR.instances["chat_messagemail"].getData();
var subject=$("#mailsuject").val();
var mailto=$("#mailto").val();
if(data&&subject&&mailto) {
try {
// Flager que l'envoit c'est fait
tosendmail=false;
$("#sendbtnmail").html("Envoyer");
$("#sendbtnmail").removeClass("btn-danger");
$("#sendbtnmail").css('cursor','auto');
// Push envent sur le websocket
event={mykey: "{{userkey}}", type: "add", message: data, mail: "true", to: mailto, subject: subject};
session.publish("websocket/channel/{{groupid}}", event);
CKEDITOR.instances["chat_message"].setData('');
// Cacher la popup
$("#sendbymail").bootstrapSwitch('state',false);
$('#mymodal-sendmail').modal('hide');
}
catch(error) {
// L'envoi ne s'est pas fait
console.log("Retry to send");
// On flag le fait de retenter l'envoit à la reconnexion
tosendmail=true;
// On signal que l'envoi est en cours sur le bouton
$("#sendbtnmail").html("Envoi en cours");
$("#sendbtnmail").addClass("btn-danger");
$("#sendbtnmail").css('cursor','progress');
}
}
else alert("Sujet, corps et destinataire(s) obligatoire");
}
$(document).on('click', '.delmessage', function(){
delmessage($(this).data("id"));
});
function delmessage(id) {
try {
// Flager que l'envoit c'est fait
todelete=false;
idtodelete=null;
// Push envent sur le websocket
event={mykey: "{{userkey}}", type: "del", id: id};
session.publish("websocket/channel/{{groupid}}", event);
}
catch(error){
// Le delete ne s'est pas fait
console.log("Retry to delete");
// On flag le fait de retenter l'envoit à la reconnexion
todelete=true;
idtodelete=id;
}
}
$(document).on('click', '#listtoavatar img', function(){
var mail = ";"+$(this).data("mail");
$("#mailto").val($("#mailto").val().replace(mail, ""));
$(this).remove();
});
function recuplastmsg() {
$.ajax({
method: "POST",
url: "{{ path('cadoles_websocket_message_list') }}",
data: {
"id": {{ groupid }},
},
success: function(datas) {
$.each(datas, function(i,data) {
// Le message a-t-il été déposé durant la déconnexion ?
if(!$("#message-"+data.id).length) {
console.log("regen message");
html ="<div id='message-"+data.id+"' class='message row'>";
html+="<div class='msgavatar'>";
html+="<img id='user_avatar_img' src='/{{ alias }}/uploads/avatar/"+data.useravatar+"' class='avatar'><br>";
if(data.userid=={{app.user.id}} || '{{ fgmanager }}'=='1') {
html+="<i class='delmessage fa fa-trash fa-fw' data-id='"+data.id+"' style='cursor: pointer;'></i>";
}
html+="</div>";
html+="<div class='msgdiv'>"
html+="<div class='msgtitle'>"+data.userlastname+"<br><small>"+new Date(data.submitdate.date).toLocaleDateString("fr-FR", dateoptions)+"</small></div>";
html+="<div class='msgtopic'>"+data.message+"</div>";
html+="</div>";
html+="</div>";
$(".mychat").prepend(html);
}
});
}
});
}
{% endif %}
{% endblock %} {% endblock %}