diff --git a/Android/BewoMitarbeiterApp/app/app.iml b/Android/BewoMitarbeiterApp/app/app.iml index fb99e4f6e..dadeec421 100644 --- a/Android/BewoMitarbeiterApp/app/app.iml +++ b/Android/BewoMitarbeiterApp/app/app.iml @@ -96,6 +96,7 @@ + diff --git a/Android/BewoMitarbeiterApp/app/src/main/java/beyondsoft/bewomitarbeiterapp/BeWoChatApplication.java b/Android/BewoMitarbeiterApp/app/src/main/java/beyondsoft/bewomitarbeiterapp/BeWoChatApplication.java index 571394f97..835c2da31 100644 --- a/Android/BewoMitarbeiterApp/app/src/main/java/beyondsoft/bewomitarbeiterapp/BeWoChatApplication.java +++ b/Android/BewoMitarbeiterApp/app/src/main/java/beyondsoft/bewomitarbeiterapp/BeWoChatApplication.java @@ -5,6 +5,22 @@ import android.app.NotificationManager; import android.content.Context; import android.util.Log; +import com.octo.android.robospice.SpiceManager; +import com.octo.android.robospice.UncachedSpiceService; +import com.octo.android.robospice.persistence.exception.SpiceException; +import com.octo.android.robospice.request.listener.RequestListener; + +import org.ksoap2.serialization.PropertyInfo; +import org.ksoap2.serialization.SoapPrimitive; + +import java.util.ArrayList; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import soapConnection.JsonSoapPrimitiveRequest; +import soapConnection.SoapCalls; import util.ConnectivityReceiver; /** @@ -13,13 +29,42 @@ import util.ConnectivityReceiver; public class BeWoChatApplication extends Application { private Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler; + private static final SpiceManager spiceManager = new SpiceManager(UncachedSpiceService.class); + private static BeWoChatApplication mInstance; + private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + @Override public void onCreate() { super.onCreate(); mInstance = this; + + spiceManager.start(this); + + keepAlive(); + } + + public void keepAlive() { + final Runnable blubb = new Runnable() { + @Override + public void run() { + JsonSoapPrimitiveRequest request = new JsonSoapPrimitiveRequest(SoapCalls.KEEP_ALIVE, new ArrayList()); + spiceManager.execute(request, new JsonSoapPrimitiveRequestListener()); + + Log.i("LOOPER", "Halte Verbindung zum Soap-Server am leben..."); + } + }; + + final ScheduledFuture blubbHandle = scheduler.scheduleAtFixedRate(blubb, 10, 10, TimeUnit.MINUTES); + + scheduler.schedule(new Runnable() { + @Override + public void run() { + blubbHandle.cancel(true); + } + }, 10, TimeUnit.DAYS); } public static synchronized BeWoChatApplication getInstance() { @@ -49,4 +94,21 @@ public class BeWoChatApplication extends Application { Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler); } + + private class JsonSoapPrimitiveRequestListener implements RequestListener { + + @Override + public void onRequestFailure(SpiceException spiceException) { + + } + + @Override + public void onRequestSuccess(SoapPrimitive soapPrimitive) { + if(soapPrimitive == null) { + Log.e("BEWOAPP", "Antwort ist null!"); + } else { + Log.i("BEWOAPP", "Die Antwort hat einen Wert"); + } + } + } } diff --git a/Android/BewoMitarbeiterApp/app/src/main/java/beyondsoft/bewomitarbeiterapp/KontaktChatActivity.java b/Android/BewoMitarbeiterApp/app/src/main/java/beyondsoft/bewomitarbeiterapp/KontaktChatActivity.java index be53bbd38..ee7bc3bd9 100644 --- a/Android/BewoMitarbeiterApp/app/src/main/java/beyondsoft/bewomitarbeiterapp/KontaktChatActivity.java +++ b/Android/BewoMitarbeiterApp/app/src/main/java/beyondsoft/bewomitarbeiterapp/KontaktChatActivity.java @@ -28,6 +28,10 @@ import java.io.ByteArrayOutputStream; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import Database.DatabaseHandler; import entities.ChatPerson; @@ -108,32 +112,6 @@ public class KontaktChatActivity extends ActionBarActivity implements Connectivi JsonSoapPrimitiveRequest request = new JsonSoapPrimitiveRequest(SoapCalls.GET_CONTACTS_FOR_PERSON, propertyInfos); spiceManager.execute(request, new JsonSoapPrimitiveRequestListener()); - - - - - -// ArrayList test = isTeam ? databaseHandler.getExistingTeamChatMessageIds() : databaseHandler.getExistingChatMessageIds(); -// -// Log.i(LOGTAG, "Chat-Messages in der Datenbank: " + test.size()); -// -// String pExceptions = ""; -// for(int i = 0; i < test.size(); i++) { -// pExceptions += test.get(i); -// -// if(i < test.size() - 1) { -// pExceptions += ";"; -// } -// } -// -// ArrayList propertyInfos2 = new ArrayList<>(); -// propertyInfos.add(SoapConnectionManager.BuildProperty("pSenderPersonOid", SoapConnectionManager.User.getPersonOid(), Long.class)); -// propertyInfos.add(SoapConnectionManager.BuildProperty("pRecipientPersonOid", recipientPersonOid, Long.class)); -// propertyInfos.add(SoapConnectionManager.BuildProperty("pExceptions", pExceptions, String.class)); -// propertyInfos.add(SoapConnectionManager.BuildProperty("pIsForTeam", isTeam, Boolean.class)); -// -// JsonSoapPrimitiveRequest request2 = new JsonSoapPrimitiveRequest(SoapCalls.GET_ALL_CHAT_MESSAGES, propertyInfos); -// spiceManager.execute(request2, new JsonSoapPrimitiveRequestListenerForUnreadMessages()); } public UIHandler kontaktChatActivityUIHandler = new UIHandler() { @@ -203,6 +181,25 @@ public class KontaktChatActivity extends ActionBarActivity implements Connectivi } }); + break; + + case STATUS_REQUEST: + + Log.i(LOGTAG, "Aktualisiere die Kontaktliste"); + + runOnUiThread(new Runnable() { + @Override + public void run() { + KontaktAdapter ka =((KontaktAdapter) listView.getAdapter()); + + for(ContactListItem item : ka.values) { + item.isOnline = SocketManager.onlinePersonOids.contains(item.getPersonOid()); + } + + ka.notifyDataSetChanged(); + } + }); + break; } } catch(Exception pe) { @@ -347,21 +344,4 @@ public class KontaktChatActivity extends ActionBarActivity implements Connectivi ((KontaktAdapter) listView.getAdapter()).notifyDataSetChanged(); } } - - private final class JsonSoapPrimitiveRequestListenerForUnreadMessages implements RequestListener { - @Override - public void onRequestFailure(SpiceException spiceException) { - Toast.makeText(KontaktChatActivity.this, "Ein Fehler ist beim laden der ungelesenen Nachrichten aufgetreten.", Toast.LENGTH_SHORT).show(); - } - - @Override - public void onRequestSuccess(SoapPrimitive soapPrimitive) { - //TODO: Nachrichten, die empfangen wurden als man offline war, laden und jeweils die neueste anzeigen. - if(soapPrimitive == null) { - Log.i("KONTAKT_CHAT_ACTIVITY", "soapPrimitive ist NULL!"); - } - - Gson gson = new GsonBuilder().create(); - } - } } diff --git a/Android/BewoMitarbeiterApp/app/src/main/java/soapConnection/DataIdentifier.java b/Android/BewoMitarbeiterApp/app/src/main/java/soapConnection/DataIdentifier.java index d5231c693..92e3393ce 100644 --- a/Android/BewoMitarbeiterApp/app/src/main/java/soapConnection/DataIdentifier.java +++ b/Android/BewoMitarbeiterApp/app/src/main/java/soapConnection/DataIdentifier.java @@ -18,7 +18,8 @@ public enum DataIdentifier { STATUS_NOTIFICATION_BESCHAEFTIGT(11), STATUS_NOTIFICATION_ONLINE(12), STATUS_NOTIFICATION_OFFLINE(13), - LOGIN_SUCCESS(14); + LOGIN_SUCCESS(14), + STATUS_REQUEST(15); private final int value; DataIdentifier(int value) { diff --git a/Android/BewoMitarbeiterApp/app/src/main/java/soapConnection/SoapCalls.java b/Android/BewoMitarbeiterApp/app/src/main/java/soapConnection/SoapCalls.java index 5cab44727..ef83a1448 100644 --- a/Android/BewoMitarbeiterApp/app/src/main/java/soapConnection/SoapCalls.java +++ b/Android/BewoMitarbeiterApp/app/src/main/java/soapConnection/SoapCalls.java @@ -9,6 +9,7 @@ public class SoapCalls { public static String GET_CONTACTS_FOR_PERSON = "GetContactsForPerson"; public static String GET_ALL_CHAT_MESSAGES = "GetAllChatMessagesForSenderAndRecipient"; + public static String KEEP_ALIVE = "KeepAlive"; //TODO: "app4.bewoplaner.de";// // public static String DESTINATION_ADDRESS = "app4.bewoplaner.de"; diff --git a/Android/BewoMitarbeiterApp/app/src/main/java/tcpConnection/SocketManager.java b/Android/BewoMitarbeiterApp/app/src/main/java/tcpConnection/SocketManager.java index 88c0397b0..382bc778e 100644 --- a/Android/BewoMitarbeiterApp/app/src/main/java/tcpConnection/SocketManager.java +++ b/Android/BewoMitarbeiterApp/app/src/main/java/tcpConnection/SocketManager.java @@ -86,7 +86,7 @@ public class SocketManager { public void run() { connectToServer(); } - }, 30000); + }, 5000); } catch(Exception exception2) { exception2.printStackTrace(); } @@ -299,6 +299,20 @@ public class SocketManager { } } + break; + + case STATUS_REQUEST: + + String contactsCsv = chatPacket.ChatMessage; + + String[] stringOids = contactsCsv.split(","); + + SocketManager.onlinePersonOids.clear(); + + for(String item : stringOids) { + SocketManager.onlinePersonOids.add(Integer.valueOf(item)); + } + break; } } catch(Exception e) { diff --git a/Android/BewoMitarbeiterApp/app/src/main/java/util/ChatMessageDeserializer.java b/Android/BewoMitarbeiterApp/app/src/main/java/util/ChatMessageDeserializer.java index 869de1d4d..e2f165a39 100644 --- a/Android/BewoMitarbeiterApp/app/src/main/java/util/ChatMessageDeserializer.java +++ b/Android/BewoMitarbeiterApp/app/src/main/java/util/ChatMessageDeserializer.java @@ -18,7 +18,6 @@ import entities.ChatMessage; * Created by JettenM on 09.08.2016. */ public class ChatMessageDeserializer implements JsonDeserializer { - private static final String LOGTAG = "MESSAGE_DESERIALIZER"; @Override public ChatMessage deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { diff --git a/Android/BewoMitarbeiterApp/app/src/main/java/util/Util.java b/Android/BewoMitarbeiterApp/app/src/main/java/util/Util.java index f3ae7d4c9..dc43bdc6f 100644 --- a/Android/BewoMitarbeiterApp/app/src/main/java/util/Util.java +++ b/Android/BewoMitarbeiterApp/app/src/main/java/util/Util.java @@ -46,7 +46,6 @@ public class Util { public static final String NOTIFICATION_CANCELLED = "notification_cancelled"; - //public static int unreadMessagesCount = 0; public static int conversationsCount = 0; public static HashMap entity2MessagesCountRel = new HashMap<>(); @@ -171,6 +170,11 @@ public class Util { Log.e("LOGIN_CALLBACK", "LoginCallback aufgerufen. Verschicke nicht verschickte Nachrichten..."); sendUnsentMessages(context); + + sendStatusRequest(); + + // TODO: Nachrichten herunterladen, sofern man sich in der ChatActivity befindet + } }; @@ -220,6 +224,17 @@ public class Util { thread.start(); } + public static void sendStatusRequest() { + final Packet requestPacket = new Packet(); + + requestPacket.ChatDataIdentifier = DataIdentifier.STATUS_REQUEST; + requestPacket.ChatName = SoapConnectionManager.User.getFullName(); + requestPacket.SenderPersonOid = SoapConnectionManager.User.getPersonOid().intValue(); + requestPacket.Tenant = SoapConnectionManager.User.getTenant(); + + SocketManager.sendMessage(requestPacket); + } + public static ChatEntity getChatEntityFromOnlineEntitiesByOid(int personOid, boolean isTeam) { for(ChatEntity item : SocketManager.onlineEntities) { if(item.getOid() == personOid && item.isTeam() == isTeam) { diff --git a/BeWoChatServer/Server.cs b/BeWoChatServer/Server.cs index bc7459271..a2083802b 100644 --- a/BeWoChatServer/Server.cs +++ b/BeWoChatServer/Server.cs @@ -315,7 +315,7 @@ namespace BeWoChatServer var notificationPacketLogout = new Packet(dataPacket.Socket, dataPacket.ClientName, dataPacket.SenderPersonOid, 0) {DataIdentifier = DataIdentifier.StatusNotificationLogout}; - Console.WriteLine(DateTime.Now + ": Sende Logout an alle anderen Clients"); + Console.WriteLine(DateTime.Now + ": Sende Logout von " + dataPacket.ClientName + " an alle anderen Clients"); foreach (var client in clientList.Where(w => !w.Value.PersonOid.Equals(dataPacket.SenderPersonOid))) { client.Key.Send(notificationPacketLogout.GetDataStream()); @@ -404,23 +404,27 @@ namespace BeWoChatServer break; - case DataIdentifier.MessageResponseToServer: + case DataIdentifier.StatusRequest: + + var onlinePersons = clientList.Where(w => w.Value.PersonOid != dataPacket.SenderPersonOid && w.Value.PersonOid > 0).Select(s => s.Value.PersonOid).Distinct().ToList(); + var oidCSV = ""; - try - { - Monitor.Enter(_Lock); + foreach (var oid in onlinePersons) + { + oidCSV += oid; - DefaultHibernateSessionManager.CurrentTenant = dataPacket.Tenant; + if (onlinePersons.IndexOf(oid) != onlinePersons.Count - 1) + { + oidCSV += ","; + } + } - var message = DAOFactory.GenericDAO.LoadByID(dataPacket.ServerseitigeOid); - message.IsDelivered = true; + if (oidCSV.Length > 0) + { + var packet = new Packet { ChatMessage = oidCSV, ClientName = dataPacket.ClientName, DataIdentifier = DataIdentifier.StatusRequest, MessageTimeStamp = DateTime.Now, Tenant = dataPacket.Tenant, SenderPersonOid = dataPacket.SenderPersonOid }; - DAOFactory.GenericDAO.Update(message); - } - finally - { - Monitor.Exit(_Lock); - } + dataPacket.Socket.Send(packet.GetDataStream()); + } break; } @@ -429,7 +433,7 @@ namespace BeWoChatServer } catch (Exception e) { - Console.WriteLine(DateTime.Now + ": Ein Fehler ist aufgetreten oder die App ist abgestürzt. Der Client wird ausgeloggt"); + Console.WriteLine(DateTime.Now + ": Ein Fehler ist aufgetreten oder die App ist abgestürzt. Der Client wird ausgeloggt (" + dataPacket.ClientName + ")"); var sender = dataPacket.Socket; diff --git a/BeWoPlanerAndroid/AndroidSoapService.asmx.cs b/BeWoPlanerAndroid/AndroidSoapService.asmx.cs index 1035d0e38..080025ce3 100644 --- a/BeWoPlanerAndroid/AndroidSoapService.asmx.cs +++ b/BeWoPlanerAndroid/AndroidSoapService.asmx.cs @@ -41,6 +41,9 @@ namespace BeWoPlanerAndroid SoapHibernateSessionManager.ConfigureHibernateSession(); + var derTimeout = Session.Timeout; + Debug.WriteLine("Timeout der Session: " + derTimeout); + var s = new UserServiceImp(); if(s.IsUserValid(pUsername, pPassword, null, "SOAPClient", false) == UserValidationResult.UserValid) @@ -100,24 +103,6 @@ namespace BeWoPlanerAndroid var messages = DAOFactory.SearchDAO.FindAllChatMessagesForAndroid(pSenderPersonOid, pRecipientPersonOid, exceptions, pIsForTeam).DoForEach(dfe => jsonMessages.Add(new ChatMessageForJson(dfe.EmpfängerPersonOid, dfe.SenderPersonOid, dfe.IsDelivered, dfe.IstGelesen, dfe.TeamOid, dfe.ChatText, dfe.Uhrzeit, dfe.Oid, dfe.InsTs))); - //messages.DoForEach(d => Debug.WriteLine("ChatText: " + Encoding.UTF8.GetString(d.ChatText) + "; ByteArray: " + d.ChatText.ToString())); - - foreach(var item in messages) - { - var str = ""; - item.ChatText.DoForEach(d => str += d.ToString() + ","); - - var abc = MapperFactory.ChatMessagesDC_ChatMessages.MapToNewDC(item); - - Debug.WriteLine("UTF-8: " + Encoding.UTF8.GetString(item.ChatText) - + "\nASCII: " + Encoding.ASCII.GetString(item.ChatText) - + "\nUTF-7: " + Encoding.UTF7.GetString(item.ChatText) - + "\nBigEndianUnicode: " + Encoding.BigEndianUnicode.GetString(item.ChatText) - + "\nUTF-32: " + Encoding.UTF32.GetString(item.ChatText)); - } - - //jsonMessages.DoForEach(m => Debug.WriteLine("Team: " + (m.TeamOid == null ? "Nein" : m.TeamOid.Value.ToString()) + "; Text: " + m.ChatText)); - return JsonConvert.SerializeObject(jsonMessages); } @@ -188,6 +173,12 @@ namespace BeWoPlanerAndroid return JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new ShouldSerializeContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); } + [WebMethod(EnableSession = true)] + public string KeepAlive() + { + return "lebt"; + } + public class ChatPerson { public long Oid { get; set; } diff --git a/Shared/BeWoEntityEnums.cs b/Shared/BeWoEntityEnums.cs index 48033354a..a2d814044 100644 --- a/Shared/BeWoEntityEnums.cs +++ b/Shared/BeWoEntityEnums.cs @@ -839,7 +839,7 @@ namespace BS.Shared StatusNotificationOnline, StatusNotificationOffline, LoginSuccess, - MessageResponseToServer + StatusRequest } public enum ChatType