Packet nach Shared verschoben

This commit is contained in:
staccatomamba
2016-07-25 09:23:22 +02:00
parent 91b2c77fc9
commit 7c43f0dca7
18 changed files with 385 additions and 327 deletions

View File

@@ -96,6 +96,7 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />

View File

@@ -4,6 +4,7 @@ import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Canvas; import android.graphics.Canvas;
@@ -17,6 +18,7 @@ import android.os.Bundle;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.util.Base64;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@@ -31,27 +33,38 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.Socket; import java.net.Socket;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import javax.crypto.NoSuchPaddingException;
import soapConnection.DataIdentifier; import soapConnection.DataIdentifier;
import soapConnection.Packet; import soapConnection.Packet;
import soapConnection.SoapConnectionManager;
import util.SecurityUtils;
import util.Util;
/** /**
* Created by bib on 03.05.2016. * Created by bib on 03.05.2016.
*/ */
public class ChatActivity extends ActionBarActivity{ public class ChatActivity extends ActionBarActivity{
private static final String LOG_TAG = "CHAT";
//View Variablen //View Variablen
protected TextView chat; protected TextView chat;
protected EditText text; protected EditText text;
@@ -59,20 +72,18 @@ public class ChatActivity extends ActionBarActivity{
//Server Variablen //Server Variablen
public static Socket socket; public static Socket socket;
protected static final String dstAddress = "192.168.1.103"; //10.0.2.2" DataOutputStream socketOutputStream;
protected static final int dstPort = 5000;
DataOutputStream st;
String SaveCompleteMS; String saveCompleteMessage;
BufferedReader in = null; // BufferedReader inputReader = null;
//Design View //Design View
protected ListView listView; protected ListView listView;
protected boolean isMe = true; protected boolean isMe = true;
protected List<ChatMessageFormat> chatMessages; public static List<ChatMessageFormat> chatMessages;
protected ArrayAdapter<ChatMessageFormat> adapter; public static ArrayAdapter<ChatMessageFormat> adapter;
ChatMessageFormat chatMessage; public static ChatMessageFormat chatMessage;
Thread currentlisten; Thread currentlisten;
@@ -119,22 +130,12 @@ public class ChatActivity extends ActionBarActivity{
titlepic.setImageBitmap(GetCircleBitmap(customerImage)); titlepic.setImageBitmap(GetCircleBitmap(customerImage));
} }
//Online Status listener
/* ImageView img = (ImageView) mCustomView.findViewById(R.id.status);
img.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ChatActivity.this.openOptionsMenu(); // activity's onCreateOptionsMenu gets called
//optionsMenu.performIdentifierAction(R.id., 0);
}
});*/
titlename.setText(name); titlename.setText(name);
action.setCustomView(mCustomView); action.setCustomView(mCustomView);
action.setDisplayShowCustomEnabled(true); action.setDisplayShowCustomEnabled(true);
senden = (Button)findViewById(R.id.Sendebutton); senden = (Button)findViewById(R.id.Sendebutton);
//chat = (TextView)findViewById(R.id.ChatText);
chatMessages = new ArrayList<>(); chatMessages = new ArrayList<>();
@@ -144,26 +145,25 @@ public class ChatActivity extends ActionBarActivity{
listView.setAdapter(adapter); listView.setAdapter(adapter);
try { try {
socket = MainActivityMitarbeiter.socket; socket = MainActivityMitarbeiter.socket;
in = MainActivityMitarbeiter.in; MainActivityMitarbeiter.Test();
//nachricht an server senden welcher name jetz aktiv connected ist
st = new DataOutputStream(socket.getOutputStream());
}catch(Exception e){/*Fail*/}
Log.i("CHAT", "listen is still alive: " + MainActivityMitarbeiter.listen.isAlive());
socketOutputStream = new DataOutputStream(socket.getOutputStream());
} catch(Exception e){
Log.e("CHAT_ERROR", "Fehler bei der Socket-Erstellung: " + e.getMessage());
}
// MainActivityMitarbeiter.listen.interrupt();
// MainActivityMitarbeiter.listen = null;
CreateFile(); CreateFile();
ReadMessageToStorage(); ReadMessageToStorage();
//Öffnet eine Verbindung zum Server //Öffnet eine Verbindung zum Server
// new Thread(new OpenConnection()).start(); //new Thread(new OpenConnection()).start();
text = (EditText)findViewById(R.id.editText); text = (EditText)findViewById(R.id.editText);
@@ -175,12 +175,12 @@ public class ChatActivity extends ActionBarActivity{
//isMe = true; //isMe = true;
if(text.getText().toString().equals("exit")){ if(text.getText().toString().equals("exit")) {
//eine möglich keit die connection zu schließen //eine möglich keit die connection zu schließen
// new Thread(new ConnectionClose()).start(); // new Thread(new ConnectionClose()).start();
}else if(!text.getText().toString().equals("")){ } else if(!text.getText().toString().equals("")) {
new Thread(new MessageSender()).start(); new Thread(new MessageSender()).start();
}else{ } else {
Toast.makeText(ChatActivity.this, "Sie müssen schon Text eingeben ", Toast.LENGTH_SHORT).show(); Toast.makeText(ChatActivity.this, "Sie müssen schon Text eingeben ", Toast.LENGTH_SHORT).show();
} }
} }
@@ -191,63 +191,54 @@ public class ChatActivity extends ActionBarActivity{
t.start(); t.start();
//MainActivityMitarbeiter.listen.sus //MainActivityMitarbeiter.listen.sus
//sharedpreferences = true;
SharedPreferences sp = getSharedPreferences(Util.PREFS_NAME, 0);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("IsInChatActivity", true);
editor.commit();
} }
/*public class OpenConnection implements Runnable{
public void run(){
try {
socket = new Socket(dstAddress,dstPort);
// Log.v("Status: ","Vorhanden 3");
//nachricht an server senden welcher name jetz aktiv connected ist
dataOutputStream = new DataOutputStream(socket.getOutputStream());
name=name+"/1";
byte[] ts = name.getBytes();
dataOutputStream.write(ts);
dataOutputStream.flush();
} catch (Exception e) {
// e.printStackTrace();
Log.v("Connection: ","Konnte nicht Aufgebaut");
socket = null;
//methode zur abfrage
}
}
}*/
public class MessageSender implements Runnable{ public class MessageSender implements Runnable{
public void run(){ public void run(){
String al = text.getText().toString();
byte[] ts = al.getBytes();
//TODO: Packet erstellen
//ChatActivity.
try{ try{
if(socket!= null ) { Log.i(LOG_TAG, "Sende Nachricht...");
if(socket != null ) {
Log.d(LOG_TAG, "Ist der Socket mit dem Server Verbunden: " + (socket.isConnected()));
Packet p = new Packet(); Packet p = new Packet();
p.ChatMessage = text.getText().toString(); p.ChatMessage = text.getText().toString();
p.SenderPersonOid = SoapConnectionManager.User.getPersonOid().intValue();
p.ChatDataIdentifier = DataIdentifier.MESSAGE; p.ChatDataIdentifier = DataIdentifier.MESSAGE;
p.ChatName = SoapConnectionManager.User.getFullName();
p.RecipientPersonOid = personOid; p.RecipientPersonOid = personOid;
st.write(p.GetDataStream()); SharedPreferences settings = getSharedPreferences(Util.PREFS_NAME, 0);
st.flush();
byte[] tenantByteArray = Base64.decode(settings.getString(Util.PREFS_TENANT_KEY, null), Base64.DEFAULT);
ByteArrayInputStream tenantStream = new ByteArrayInputStream(tenantByteArray);
p.Tenant = SecurityUtils.decrypt(tenantStream).toString();
socketOutputStream.write(p.GetDataStream());
socketOutputStream.flush();
}
else {
Log.i("SEND_CHAT_MESSAGE","Socket ist null");
} }
// Update der GUI // Update der GUI
listView.post(new Runnable() { listView.post(new Runnable() {
@Override @Override
public void run() { public void run() {
Log.i(LOG_TAG, "Führe GUI-Update durch...");
Calendar c = Calendar.getInstance(); Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String formattedDate = df.format(c.getTime()); String formattedDate = df.format(c.getTime());
SaveCompleteMS = text.getText().toString()+"/"+isMe+"%"+formattedDate+"\n"; saveCompleteMessage = text.getText().toString()+"/"+isMe+"%"+formattedDate+"\n";
WriteMessagesfromStorage(text.getText().toString()+"/"+isMe+"%"+formattedDate+"\n"); WriteMessagesfromStorage(text.getText().toString()+"/"+isMe+"%"+formattedDate+"\n");
@@ -256,113 +247,73 @@ public class ChatActivity extends ActionBarActivity{
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
text.setText(""); text.setText("");
} }
}); });
}catch(IOException s){ }catch(IOException s){
Log.v("Status: ","Senden einer Nachricht konnte nicht ausgeführt werden. Save wird ausgeführt"); Log.v("Status: ","Senden einer Nachricht konnte nicht ausgeführt werden. Save wird ausgeführt");
SaveAfterLoseConnection(SaveCompleteMS); SaveAfterLoseConnection(saveCompleteMessage);
s.printStackTrace(); s.printStackTrace();
} catch (NoSuchPaddingException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
} }
} }
} }
/* public class ConnectionClose implements Runnable{
public void run(){
try {
// Log.v("Bin ich Überhaupt", "Hier drinne");
if (dataOutputStream != null) {
dataOutputStream.flush();
dataOutputStream.close();
}
if (socket != null)
socket = null;
// Log.v("Schliesen :","?? Möglich");
// }
Log.v("Status","Socket succesfull closed");
}catch(IOException se){
Log.v("Status: ","Schließen nicht möglich. Es ist ein Fehler aufgetreten");
}
}
}*/
// Erhalte Messages all the time // Erhalte Messages all the time
public class SocketListener implements Runnable{ public class SocketListener implements Runnable{
String str; Packet chatPacket;
long i = 1;
//BufferedReader in = null;
public void run(){ public void run(){
try{ try{
//DesignTechnische gründe
Log.v("Komme","ICh den Rein");
while(true){ while(true){
if (socket != null) { if (socket != null) {
Log.v("Komme","So wie es aussieht nicht ");
if(socket.isConnected()) { if(socket.isConnected()) {
Log.v("Connection Steht ", "Connection Steht");
Log.v("Komme","So wie es aussieht nicht2 ");
//final TextView text = (TextView)findViewById(R.id.ChatText);
final ListView listV = (ListView) findViewById(R.id.list_msg); final ListView listV = (ListView) findViewById(R.id.list_msg);
Log.v("Komme","So wie es aussieht nicht 3"); InputStream stream = socket.getInputStream();
// in = new BufferedReader(new InputStreamReader(MainActivityMitarbeiter.socket.getInputStream()));
/*---> da wird das pendant ausgeführt und nicht dieses */ String s = in.readLine(); int size = stream.available();
Log.v("Komme","So wie es aussieht nicht 4");
CharSequence cs = text.getText();
// wir nehmen mal cs raus if(size == 0) {
//str = cs + "\r\n" + s; continue;
str = s; }
if (s == null) Log.i("", "");
break;
StringBuilder total = new StringBuilder(stream.available());
int counter = 0;
while(counter < size) {
char c = (char) stream.read();
total.append(c);
counter++;
}
chatPacket = new Packet(total.toString());
//Design Spezifisch
listV.post(new Runnable() { listV.post(new Runnable() {
@Override @Override
public void run() { public void run() {
Calendar c = Calendar.getInstance(); WriteMessagesfromStorage(chatPacket.ChatMessage + "/" + false + "%" + chatPacket.getFormattedMessageTimeStamp() + "\n");
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String formattedDate = df.format(c.getTime());
boolean determind = false; chatMessage = new ChatMessageFormat(chatPacket.ChatMessage, false, chatPacket.getFormattedMessageTimeStamp());
WriteMessagesfromStorage(str+"/"+determind+"%"+formattedDate+"\n");
chatMessage = new ChatMessageFormat(str, determind, formattedDate);
chatMessages.add(chatMessage); chatMessages.add(chatMessage);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
Log.v("","");
if(isOnStop == true){
SetNotify("Bärtiger Hanz",str);
}
} }
}); });
} else {
i++; Log.i("SOCKETLISTENER/CHAT", "Nicht mit dem Socket verbunden");
} }
} else {
if (in != null)
in.close();
} }
// else Log.v("Connection","nicht aufgebaut"); nach tausend versuchen break und fehler ausgabe
} }
}catch(Exception e){ }catch(Exception e){
Log.v("Status ","Verbindung zum Server wurde seitens dem Server getrennt "); Log.e("Status ","Verbindung zum Server wurde seitens dem Server getrennt ");
// Log.e(getClass().getName(),e.getMessage());
// e.printStackTrace();
} }
} }
} }
@@ -433,11 +384,11 @@ public class ChatActivity extends ActionBarActivity{
byte[] ts = al.getBytes(); byte[] ts = al.getBytes();
try { try {
if (socket != null && st != null) { if (socket != null && socketOutputStream != null) {
//try catch bei catch SaveAfterLoseConnection(); //try catch bei catch SaveAfterLoseConnection();
st.write(ts); socketOutputStream.write(ts);
st.flush(); socketOutputStream.flush();
} }
}catch(Exception xs){ }catch(Exception xs){
@@ -518,9 +469,12 @@ public class ChatActivity extends ActionBarActivity{
} }
public void onResume() { public void onResume() {
isOnStop = false;
SharedPreferences sp = getSharedPreferences(Util.PREFS_NAME, 0);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("IsInChatActivity", true);
editor.commit();
super.onResume(); super.onResume();
} }
@@ -529,9 +483,12 @@ public class ChatActivity extends ActionBarActivity{
// Thread t = new Thread(new ConnectionClose()); // Thread t = new Thread(new ConnectionClose());
// t.start(); // t.start();
SharedPreferences sp = getSharedPreferences(Util.PREFS_NAME, 0);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("IsInChatActivity", false);
editor.commit();
isOnStop = true;
super.onStop(); super.onStop();
} }
@@ -539,7 +496,10 @@ public class ChatActivity extends ActionBarActivity{
// Thread t = new Thread(new ConnectionClose()); // Thread t = new Thread(new ConnectionClose());
// t.start(); // t.start();
// currentlisten = null; // currentlisten = null;
SharedPreferences sp = getSharedPreferences(Util.PREFS_NAME, 0);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("IsInChatActivity", false);
editor.commit();
super.onDestroy(); super.onDestroy();
} }

View File

@@ -5,9 +5,11 @@ import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color; import android.graphics.Color;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
import android.os.Bundle; import android.os.Bundle;
import android.util.Base64;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@@ -15,11 +17,12 @@ import android.view.View;
import android.widget.Button; import android.widget.Button;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStream;
import java.net.Socket; import java.net.Socket;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
@@ -31,6 +34,9 @@ import soapConnection.Packet;
import soapConnection.SoapCalls; import soapConnection.SoapCalls;
import soapConnection.SoapConnectionManager; import soapConnection.SoapConnectionManager;
import util.SecurityUtils;
import util.Util;
public class MainActivityMitarbeiter extends Activity { public class MainActivityMitarbeiter extends Activity {
@@ -39,10 +45,8 @@ public class MainActivityMitarbeiter extends Activity {
protected Button logoutbutton; protected Button logoutbutton;
public static Socket socket; public static Socket socket;
protected static final String dstAddress = SoapCalls.DESTINATION_ADDRESS;
protected static final int dstPort = 5000;
DataOutputStream dataOutputStream; DataOutputStream dataOutputStream;
public static BufferedReader in = null; // public static BufferedReader inputReader = null;
//Name, der Zum Server gesendet wird //Name, der Zum Server gesendet wird
protected String name; protected String name;
@@ -55,7 +59,7 @@ public class MainActivityMitarbeiter extends Activity {
File Unsendfile; File Unsendfile;
public static Thread listen; public static Thread listen;
public static SocketListener socketListener;
//Für Notification //Für Notification
private static boolean isOnStop = false; private static boolean isOnStop = false;
@@ -139,7 +143,7 @@ public class MainActivityMitarbeiter extends Activity {
public class OpenConnection implements Runnable{ public class OpenConnection implements Runnable{
public void run(){ public void run(){
try { try {
socket = new Socket(dstAddress, dstPort); socket = new Socket(SoapCalls.DESTINATION_ADDRESS, SoapCalls.DESTINATION_PORT);
Log.d("OpenConnection","Verbindung hergestellt"); Log.d("OpenConnection","Verbindung hergestellt");
SendAfterGetConnection(); SendAfterGetConnection();
@@ -152,7 +156,8 @@ public class MainActivityMitarbeiter extends Activity {
// dataOutputStream.flush(); // dataOutputStream.flush();
// Starte SocketListener // Starte SocketListener
listen = new Thread(new SocketListener()); socketListener = new SocketListener();
listen = new Thread(socketListener);
listen.start(); listen.start();
} catch (Exception e) { } catch (Exception e) {
@@ -174,54 +179,60 @@ public class MainActivityMitarbeiter extends Activity {
} }
} }
public static void Test() {
if(listen.isAlive()) {
try {
socketListener.terminate();
listen.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class SocketListener implements Runnable { public class SocketListener implements Runnable {
String str; private volatile boolean running = true;
public void terminate() {
running = false;
}
public void run() { public void run() {
try { try {
while (true) { while (running) {
if (socket != null) { if (socket != null) {
if (socket.isConnected()) { //----------> isThreadPausabfrage das könnte das Problem mit dem SocketListener vorort beheben if (socket.isConnected()) { //----------> isThreadPausabfrage das könnte das Problem mit dem SocketListener vorort beheben
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); InputStream stream = socket.getInputStream();
Log.v("Connection Steht ", "Message Erhalten");
String s = in.readLine();
String[] splitt = s.split(":"); int size = stream.available();
str = s; if(size == 0) {
continue;
if (s == null) {
break;
} }
Calendar c = Calendar.getInstance(); StringBuilder total = new StringBuilder(stream.available());
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String formattedDate = df.format(c.getTime());
boolean determind = false; int counter = 0;
Log.v("MESSAGE",splitt[0]); while(counter < size) {
CreateFile(splitt[0]);
Log.v("MESSAGE", "Komme ich in den Save-Bereich hinein"); char c = (char) stream.read();
WriteMessagesfromStorage(splitt[1] + "/" + determind + "%" + formattedDate + "\n"); total.append(c);
SetNotify(splitt[0], splitt[1]); counter++;
} else {
if (in != null) {
in.close();
} }
Log.i("MESSAGE/MAIN", "Empfangene Nachricht: " + total.toString());
} }
} }
} }
} catch(Exception e) { } catch(Exception e) {
Log.v("Status ","Verbindung zum Server wurde serverseitig getrennt "); Log.e("Listener/Main", "" + e);
// Log.e(getClass().getName(),e.getMessage());
in = null; e.printStackTrace();
} }
} }
} }
@@ -238,13 +249,9 @@ public class MainActivityMitarbeiter extends Activity {
socket.close(); socket.close();
} }
if(in != null) { Log.i("MAIN CONNECTION CLOSE","Socket succesfully closed");
in = null;
}
Log.v("Status","Socket succesfully closed");
}catch(IOException se){ }catch(IOException se){
Log.v("Fehler Aufgetreten",se.getMessage()); Log.e("MAIN ERROR:", se.getMessage());
} }
} }
} }
@@ -274,9 +281,14 @@ public class MainActivityMitarbeiter extends Activity {
if(socket.isConnected()) { if(socket.isConnected()) {
try { try {
Packet p = new Packet(); Packet p = new Packet();
p.ChatName = SoapConnectionManager.User.getFullName();
SharedPreferences settings = getSharedPreferences(Util.PREFS_NAME, 0);
byte[] tenantByteArray = Base64.decode(settings.getString(Util.PREFS_TENANT_KEY, null), Base64.DEFAULT);
ByteArrayInputStream tenantStream = new ByteArrayInputStream(tenantByteArray);
p.Tenant = SecurityUtils.decrypt(tenantStream).toString();
p.ChatDataIdentifier = DataIdentifier.LOGIN; p.ChatDataIdentifier = DataIdentifier.LOGIN;
p.SenderPersonOid = SoapConnectionManager.User.getPersonOid().intValue();
new Thread(new TestMessageSender(p.GetDataStream())).start(); new Thread(new TestMessageSender(p.GetDataStream())).start();
} catch(Exception e) { } catch(Exception e) {

View File

@@ -18,8 +18,6 @@ public class MessageAdapter extends ArrayAdapter<ChatMessageFormat> {
private Activity activity; private Activity activity;
private List<ChatMessageFormat> messages; private List<ChatMessageFormat> messages;
public MessageAdapter(Activity context, int resource, List<ChatMessageFormat> objects) { public MessageAdapter(Activity context, int resource, List<ChatMessageFormat> objects) {
super(context, resource, objects); super(context, resource, objects);
this.activity = context; this.activity = context;
@@ -36,37 +34,21 @@ public class MessageAdapter extends ArrayAdapter<ChatMessageFormat> {
ChatMessageFormat chatMessage = getItem(position); ChatMessageFormat chatMessage = getItem(position);
int viewType = getItemViewType(position); int viewType = getItemViewType(position);
//Splitt message um zu wissen ob from server oder nicht //Splitt message um zu wissen ob from server oder nicht
String line = chatMessage.getMessage(); // String line = chatMessage.getMessage();
String[] splitt = line.split(":");
//Server nachricht kenntlich machen //Server nachricht kenntlich machen
if (chatMessage.getIsME()) { if (chatMessage.getIsME()) {
layoutResource = R.layout.item_chat_right; layoutResource = R.layout.item_chat_right;
} else if(splitt[0].equals("Server")) { // } else if(splitt[0].equals("Server")) {
layoutResource = R.layout.item_chat_sever_right; // layoutResource = R.layout.item_chat_sever_right;
}else { }else {
layoutResource = R.layout.item_chat_left; layoutResource = R.layout.item_chat_left;
} }
/* Original
if (chatMessage.getIsME()) {
layoutResource = R.layout.item_chat_left;
} else {
layoutResource = R.layout.item_chat_right;
}
*/
/* if (convertView != null) {
holder = (ViewHolder) convertView.getTag();
Log.v("Status","Bin ich hier ?? ");
} else {*/
convertView = inflater.inflate(layoutResource, parent, false); convertView = inflater.inflate(layoutResource, parent, false);
holder = new ViewHolder(convertView); holder = new ViewHolder(convertView);
convertView.setTag(holder); convertView.setTag(holder);
//}
//set message content //set message content
holder.msg.setText(chatMessage.getMessage()); holder.msg.setText(chatMessage.getMessage());
@@ -74,8 +56,9 @@ public class MessageAdapter extends ArrayAdapter<ChatMessageFormat> {
//TODO eine weitere option für Chatmessage hinzufügen zum abfragen wegen send Message //TODO eine weitere option für Chatmessage hinzufügen zum abfragen wegen send Message
if(holder.send_tick != null) if(holder.send_tick != null) {
holder.send_tick.setText(Html.fromHtml("&#x2713;")+""+Html.fromHtml("&#x2713;")); holder.send_tick.setText(Html.fromHtml("&#x2713;") + "" + Html.fromHtml("&#x2713;"));
}
if(chatMessage.getIsME()){ if(chatMessage.getIsME()){

View File

@@ -7,7 +7,8 @@ public enum DataIdentifier {
MESSAGE(0), MESSAGE(0),
LOGIN(1), LOGIN(1),
LOGOUT(2), LOGOUT(2),
NULL(3); NULL(3),
STATUS_NOTIFICATION(4);
private final int value; private final int value;
DataIdentifier(int value) { DataIdentifier(int value) {
@@ -17,4 +18,16 @@ public enum DataIdentifier {
public int getValue() { public int getValue() {
return value; return value;
} }
public static DataIdentifier getEnumValue(int pValue) {
DataIdentifier[] identifiers = DataIdentifier.values();
for (DataIdentifier identifier : identifiers) {
if (identifier.getValue() == pValue) {
return identifier;
}
}
return DataIdentifier.NULL;
}
} }

View File

@@ -4,7 +4,13 @@ import android.util.Log;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer; import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/** /**
* Created by JettenM on 05.07.2016. * Created by JettenM on 05.07.2016.
@@ -15,29 +21,73 @@ public class Packet {
public int SenderPersonOid; public int SenderPersonOid;
public int RecipientPersonOid; public int RecipientPersonOid;
public String ChatMessage; public String ChatMessage;
public Date MessageTimeStamp;
public String Tenant;
public Packet() { public Packet() {
ChatDataIdentifier = DataIdentifier.NULL; ChatDataIdentifier = DataIdentifier.NULL;
ChatMessage = null; ChatMessage = "";
ChatName = null; ChatName = SoapConnectionManager.User.getFullName();
SenderPersonOid = 0; Tenant = "";
SenderPersonOid = SoapConnectionManager.User.getPersonOid().intValue();
RecipientPersonOid = 0; RecipientPersonOid = 0;
MessageTimeStamp = Calendar.getInstance().getTime();
} }
public String getFormattedMessageTimeStamp() {
DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
return df.format(MessageTimeStamp);
}
public Packet(byte[] dataStream) { //Aufbau Message:
ChatDataIdentifier = DataIdentifier.values()[ByteBuffer.allocate(4).getInt()]; // die ersten fünf ";" ignorieren
// SenderOid;RecipientOid;ClientNameLength;MessageLength;ChatDataIdentifier;Tenant;[ClientName][ChatMessage][MessageTimeStamp]
//23;281;20;389;1;[Tenant]; 6 Semikola
public Packet(String message) {
String[] gesplittet = message.split(";");
String senderPersonOidString = gesplittet[0];
String recipientPersonOidString = gesplittet[1];
String chatNameLengthString = gesplittet[2];
String chatMessageLengthString = gesplittet[3];
String chatIdentifierString = gesplittet[4];
Tenant = gesplittet[5];
SenderPersonOid = Integer.parseInt(senderPersonOidString);
RecipientPersonOid = Integer.parseInt(recipientPersonOidString);
ChatDataIdentifier = DataIdentifier.getEnumValue(Integer.parseInt(chatIdentifierString));
int chatNameLength = Integer.parseInt(chatNameLengthString);
int chatMessageLength = Integer.parseInt(chatMessageLengthString);
int headerLength = senderPersonOidString.length() + recipientPersonOidString.length() + chatNameLengthString.length() + chatMessageLengthString.length() + chatIdentifierString.length() + Tenant.length() + 7;
String actualMessage = message.substring(headerLength - 1);
ChatName = actualMessage.substring(0, chatNameLength);
ChatMessage = actualMessage.substring(chatNameLength, chatMessageLength + chatNameLength);
String dateString = actualMessage.substring(chatMessageLength + chatNameLength);
DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss", Locale.GERMAN);
try {
MessageTimeStamp = df.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
} }
public byte[] GetDataStream() { public byte[] GetDataStream() {
String dataStreamAsString = "" + SenderPersonOid + ";" + RecipientPersonOid + ";" + ChatName.length() + ";" + ChatMessage.length() + ";"; String dataStreamAsString = "" + SenderPersonOid + ";" + RecipientPersonOid + ";" + ChatName.length() + ";" + ChatMessage.length()+ ";" + ChatDataIdentifier.getValue() + ";" + Tenant + ";";
dataStreamAsString += ChatName + ChatMessage; dataStreamAsString += ChatName + ChatMessage + getFormattedMessageTimeStamp();
byte[] blaaah = new byte[1024]; byte[] blaaah = new byte[dataStreamAsString.length()];
try { try {
blaaah = dataStreamAsString.getBytes("UTF8"); blaaah = dataStreamAsString.getBytes("UTF8");

View File

@@ -9,6 +9,7 @@ public class SoapCalls {
public static String GET_CONTACTS_FOR_PERSON = "GetContactsForPerson"; public static String GET_CONTACTS_FOR_PERSON = "GetContactsForPerson";
public static String DESTINATION_ADDRESS = "192.168.1.103"; public static String DESTINATION_ADDRESS = "192.168.1.103";
public static int DESTINATION_PORT = 5000;
public static String TOKEN_CHECK_URL = "http://" + DESTINATION_ADDRESS + "/bewoplanermobil/main/checktoken?token="; public static String TOKEN_CHECK_URL = "http://" + DESTINATION_ADDRESS + "/bewoplanermobil/main/checktoken?token=";

View File

@@ -42,6 +42,7 @@
android:id="@+id/editText" android:id="@+id/editText"
android:hint="@string/hinttxt_chat" android:hint="@string/hinttxt_chat"
android:padding="10dp" android:padding="10dp"
android:maxLength="1024"
/> />
<!-- width -> 300dp heigh -> 60dp android:layout_marginBottom="30dp" android:layout_marginBottom="30dp" <!-- width -> 300dp heigh -> 60dp android:layout_marginBottom="30dp" android:layout_marginBottom="30dp"

View File

@@ -69,7 +69,6 @@
<Reference Include="WindowsBase" /> <Reference Include="WindowsBase" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Packet.cs" />
<Compile Include="Server.cs" /> <Compile Include="Server.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>

View File

@@ -1,82 +0,0 @@
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using BS.Shared;
namespace BeWoChatServer
{
public class Packet
{
public Socket Socket { get; set; }
public int ClientNumber { get; set; }
public string ClientName { get; set; }
public long SenderPersonOid { get; set; }
public long RecipientPersonOid { get; set; }
public DataIdentifier DataIdentifier { get; set; }
public string ChatMessage { get; set; }
public byte[] DataBuffer = new byte[1024];
public Packet(Socket pSocket, int pClientNumber, string pClientName, long pSenderPersonOid, long pRecipientPersonOid)
{
Socket = pSocket;
ClientNumber = pClientNumber;
ClientName = pClientName;
SenderPersonOid = pSenderPersonOid;
RecipientPersonOid = pRecipientPersonOid;
}
// 0 4 8 12 20 28
// Description -> |dataIdentifier|name length|message length|sender person oid|recipient person oid| name | message |
// Size in bytes -> | 4 | 4 | 4 | 8 | 8 |name length|message length|
public Packet(byte[] dataStream)
{
DataIdentifier = (DataIdentifier)BitConverter.ToInt32(dataStream, 0);
var nameLength = BitConverter.ToInt32(dataStream, 4);
var messageLength = BitConverter.ToInt32(dataStream, 8);
SenderPersonOid = BitConverter.ToInt64(dataStream, 12);
RecipientPersonOid = BitConverter.ToInt64(dataStream, 20);
ClientName = nameLength > 0 ? Encoding.UTF8.GetString(dataStream, 28, nameLength) : null;
ChatMessage = messageLength > 0 ? Encoding.UTF8.GetString(dataStream, 28 + nameLength, messageLength) : null;
}
public void GetData(string message)
{
//Aufbau Message:
// die ersten fünf ";" ignorieren
// SenderOid;RecipientOid;ClientNameLength;MessageLength;ChatDataIdentifier;ClientNameChatMessage
//23;281;20;389;1; 5 Semikola
var gesplittet = message.Split(';');
SenderPersonOid = Convert.ToInt64(gesplittet[0]);
RecipientPersonOid = Convert.ToInt64(gesplittet[1]);
var chatNameLength = Convert.ToInt32(gesplittet[2]);
var chatMessageLength = Convert.ToInt32(gesplittet[3]);
var headerLength = gesplittet[0].Length + gesplittet[1].Length + gesplittet[2].Length + gesplittet[3].Length + 5;
var actualMessage = message.Substring(headerLength - 1);
ClientName = actualMessage.Substring(0, chatNameLength);
ChatMessage = actualMessage.Substring(chatNameLength);
}
// Java kennt nur unsigned bytes (-127 bis 128)
public byte[] GetDataStream()
{
var result = "";
return Encoding.UTF8.GetBytes(result);
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using BeWo.Data; using BeWo.Data;
using BeWo.Data.Access; using BeWo.Data.Access;
using BeWo.Data.Entities; using BeWo.Data.Entities;
@@ -16,7 +17,10 @@ namespace BeWoChatServer
{ {
public class Server public class Server
{ {
private static object _Lock = string.Empty; // Fehlercodes zwischen 1000 und 1499
//TODO: Login hier implementieren und das andere Projekt löschen
private static readonly object _Lock = string.Empty;
private static readonly Dictionary<Socket, long> clientList = new Dictionary<Socket, long>(); private static readonly Dictionary<Socket, long> clientList = new Dictionary<Socket, long>();
protected static Socket serverSocket; protected static Socket serverSocket;
@@ -25,17 +29,10 @@ namespace BeWoChatServer
private static int clientCount; private static int clientCount;
static Packet dataPacketsdf;
public static void Main(string[] args) public static void Main(string[] args)
{ {
try try
{ {
// Benutzt den DefaultHibernateSessionManager
DefaultHibernateSessionManager.CurrentTenant = "demo";
DefaultHibernateSessionManager.OpenSession();
var test = DAOFactory.GenericDAO.LoadByID<ChatMessage>(1);
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var server = new IPEndPoint(IPAddress.Any, 5000); var server = new IPEndPoint(IPAddress.Any, 5000);
@@ -53,8 +50,6 @@ namespace BeWoChatServer
} }
} }
//TODO: Datenbankverbindung herstellen
public static void OnClientConnected(IAsyncResult asyncResult) public static void OnClientConnected(IAsyncResult asyncResult)
{ {
try try
@@ -65,7 +60,7 @@ namespace BeWoChatServer
clientList.Add(workerSocket, 0); clientList.Add(workerSocket, 0);
WaitForClientData(workerSocket, clientCount, "LEER", 0, 0); WaitForClientData(workerSocket, "", 0, 0);
serverSocket.BeginAccept(OnClientConnected, null); serverSocket.BeginAccept(OnClientConnected, null);
} }
@@ -75,7 +70,7 @@ namespace BeWoChatServer
} }
} }
public static void WaitForClientData(Socket socket, int clientNumber, string clientName, long oid, long recipientPersonOid) public static void WaitForClientData(Socket socket, string clientName, long oid, long recipientPersonOid)
{ {
try try
{ {
@@ -84,7 +79,7 @@ namespace BeWoChatServer
asyncCallback = OnReceiveData; asyncCallback = OnReceiveData;
} }
var packet = new Packet(socket, clientNumber, clientName, oid, recipientPersonOid); var packet = new Packet(socket, clientName, oid, recipientPersonOid);
socket.BeginReceive(packet.DataBuffer, 0, packet.DataBuffer.Length, SocketFlags.None, asyncCallback, packet); socket.BeginReceive(packet.DataBuffer, 0, packet.DataBuffer.Length, SocketFlags.None, asyncCallback, packet);
} }
@@ -98,6 +93,8 @@ namespace BeWoChatServer
{ {
var dataPacket = (Packet) asyncResult.AsyncState; var dataPacket = (Packet) asyncResult.AsyncState;
Debug.WriteLine("Nachricht erhalten " + DateTime.Now);
try try
{ {
var responseByteCount = dataPacket.Socket.EndReceive(asyncResult); var responseByteCount = dataPacket.Socket.EndReceive(asyncResult);
@@ -114,8 +111,6 @@ namespace BeWoChatServer
dataPacket.GetData(message); dataPacket.GetData(message);
} }
// Nur bei DataIdentifier.Login
//TODO: SenderOid im Dictionary speichern
switch(dataPacket.DataIdentifier) { switch(dataPacket.DataIdentifier) {
case DataIdentifier.Login: case DataIdentifier.Login:
var endPoint = dataPacket.Socket.RemoteEndPoint; var endPoint = dataPacket.Socket.RemoteEndPoint;
@@ -127,6 +122,12 @@ namespace BeWoChatServer
{ {
clientList[dataPacket.Socket] = dataPacket.SenderPersonOid; clientList[dataPacket.Socket] = dataPacket.SenderPersonOid;
} }
//foreach(var client in clientList)
//{
// client.Key.Send(Encoding.UTF8.GetBytes("Client eingeloggt"));
//}
break; break;
case DataIdentifier.Message: case DataIdentifier.Message:
if(responseByteCount == 0) if(responseByteCount == 0)
@@ -136,21 +137,37 @@ namespace BeWoChatServer
} }
else else
{ {
try try
{ {
Monitor.Enter(_Lock); Monitor.Enter(_Lock);
DefaultHibernateSessionManager.CurrentTenant = "demo"; DefaultHibernateSessionManager.CurrentTenant = dataPacket.Tenant;
var chatMessage = new ChatMessage
{
SenderPersonOid = dataPacket.SenderPersonOid,
ChatText = dataPacket.ChatMessage,
EmpfängerPersonOid = dataPacket.RecipientPersonOid,
Uhrzeit = dataPacket.MessageTimeStamp,
InsUser = dataPacket.ClientName
};
DAOFactory.GenericDAO.Insert(chatMessage);
if(dataPacket.RecipientPersonOid > 0 && clientList.ContainsValue(dataPacket.RecipientPersonOid))
{
var recipients = clientList.Where(w => w.Value.Equals(dataPacket.RecipientPersonOid));
foreach(var recipient in recipients)
{
recipient.Key.Send(dataPacket.GetDataStream());
}
}
} }
finally finally
{ {
Monitor.Exit(_Lock); Monitor.Exit(_Lock);
} }
// in DB speichern und an evtl. an den Empfänger schicken, sofern dieser in der clientList enthalten ist
} }
break; break;
@@ -158,10 +175,18 @@ namespace BeWoChatServer
break; break;
} }
WaitForClientData(dataPacket.Socket, dataPacket.ClientNumber, dataPacket.ClientName, dataPacket.SenderPersonOid, dataPacket.RecipientPersonOid); WaitForClientData(dataPacket.Socket, dataPacket.ClientName, dataPacket.SenderPersonOid, dataPacket.RecipientPersonOid);
} }
catch (Exception e) catch (Exception e)
{ {
var sender = dataPacket.Socket;
if(clientList.ContainsKey(sender))
{
clientList.Remove(sender);
sender.Close();
}
Debug.WriteLine("ChatServerException: " + e.Message); Debug.WriteLine("ChatServerException: " + e.Message);
} }
} }

Binary file not shown.

View File

@@ -1,7 +1,9 @@
using System.Linq; using System;
using System.Linq;
using System.Web.Services; using System.Web.Services;
using BeWo.Data.Access; using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.ServiceContracts; using BeWo.Service.ServiceContracts;
using BeWo.Service.ServiceImplementations; using BeWo.Service.ServiceImplementations;

View File

@@ -60,12 +60,11 @@ namespace BeWo.Data
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory; var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var splittedBaseDirectory = baseDirectory.Split('\\'); // 0 -3 var splittedBaseDirectory = baseDirectory.Split('\\'); // 0 -3
var correctBaseDirectory = string.Empty; var correctBaseDirectory = string.Empty;
for(var i = 0; i < 4; i++) for(var i = 0; i < 4; i++)
{ {
correctBaseDirectory += splittedBaseDirectory[i] + "\\"; correctBaseDirectory += splittedBaseDirectory[i] + "\\";
} }
var test = correctBaseDirectory;
_SessionFactories[CurrentTenant] = new Configuration().Configure(Path.Combine(correctBaseDirectory, @"Multitenancy\" + CurrentTenant + ".config")).BuildSessionFactory(); _SessionFactories[CurrentTenant] = new Configuration().Configure(Path.Combine(correctBaseDirectory, @"Multitenancy\" + CurrentTenant + ".config")).BuildSessionFactory();
} }

View File

@@ -22,6 +22,10 @@ namespace BeWo.Data.Entities
private long? _SenderPersonOid; private long? _SenderPersonOid;
public ChatMessage()
{
_Tid = TableID.ChatMessage;
}
public virtual string ChatText public virtual string ChatText
{ {

View File

@@ -827,6 +827,7 @@ namespace BS.Shared
Message, Message,
Login, Login,
Logout, Logout,
Null Null,
StatusNotification
} }
} }

88
Shared/Packet.cs Normal file
View File

@@ -0,0 +1,88 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.Net.Sockets;
using System.Text;
using BS.Shared;
namespace BeWoChatServer
{
public class Packet
{
// Fehlercodes zwischen 1500 und 1999
public Socket Socket { get; set; }
public string ClientName { get; set; }
public long SenderPersonOid { get; set; }
public long RecipientPersonOid { get; set; }
public DataIdentifier DataIdentifier { get; set; }
public string ChatMessage { get; set; }
public DateTime MessageTimeStamp { get; set; }
public string Tenant { get; set; }
public byte[] DataBuffer = new byte[1024];
//Aufbau Message:
// die ersten fünf ";" ignorieren
// SenderOid;RecipientOid;ClientNameLength;MessageLength;ChatDataIdentifier;Tenant;[ClientName][ChatMessage][MessageTimeStamp]
//23;281;20;389;1;[Tenant]; 6 Semikola
public Packet(Socket pSocket, string pClientName, long pSenderPersonOid, long pRecipientPersonOid)
{
Socket = pSocket;
ClientName = pClientName;
SenderPersonOid = pSenderPersonOid;
RecipientPersonOid = pRecipientPersonOid;
MessageTimeStamp = DateTime.Now;
}
public void GetData(string message)
{
Debug.WriteLine("Nachricht: " + message);
try
{
var gesplittet = message.Split(';');
var senderPersonOidString = gesplittet[0];
var recipientPersonOidString = gesplittet[1];
var chatNameLengthString = gesplittet[2];
var chatMessageLengthString = gesplittet[3];
var chatIdentifierString = gesplittet[4];
Tenant = gesplittet[5];
DataIdentifier = (DataIdentifier) Convert.ToInt32(chatIdentifierString);
SenderPersonOid = Convert.ToInt64(senderPersonOidString);
RecipientPersonOid = Convert.ToInt64(recipientPersonOidString);
var chatNameLength = Convert.ToInt32(chatNameLengthString);
var chatMessageLength = Convert.ToInt32(chatMessageLengthString);
var headerLength = senderPersonOidString.Length + recipientPersonOidString.Length + chatNameLengthString.Length + chatMessageLengthString.Length + chatIdentifierString.Length + Tenant.Length + 7;
var actualMessage = message.Substring(headerLength - 1);
ClientName = actualMessage.Substring(0, chatNameLength);
ChatMessage = actualMessage.Substring(chatNameLength, chatMessageLength);
var dateString = actualMessage.Substring(chatMessageLength + chatNameLength);
MessageTimeStamp = DateTime.ParseExact(dateString, "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
catch(Exception exception)
{
Debug.WriteLine("Error 1500: " + exception.Message);
}
}
public byte[] GetDataStream()
{
var result = "";
result += SenderPersonOid + ";" + RecipientPersonOid + ";" + ClientName.Length + ";" + ChatMessage.Length + ";" + (int) DataIdentifier + ";" + Tenant + ";" + ClientName + ChatMessage + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss");
return Encoding.UTF8.GetBytes(result);
}
}
}

View File

@@ -216,6 +216,7 @@
<Compile Include="Extensions\EnumExtensions.cs" /> <Compile Include="Extensions\EnumExtensions.cs" />
<Compile Include="Extensions\ICollectionExtensions.cs" /> <Compile Include="Extensions\ICollectionExtensions.cs" />
<Compile Include="Extensions\IDictionaryTExtensions.cs" /> <Compile Include="Extensions\IDictionaryTExtensions.cs" />
<Compile Include="Packet.cs" />
<Compile Include="Rss\RssManager.cs" /> <Compile Include="Rss\RssManager.cs" />
<Compile Include="Services\BillingData.cs" /> <Compile Include="Services\BillingData.cs" />
<Compile Include="Services\Calculations.cs" /> <Compile Include="Services\Calculations.cs" />