ServerSocial: complete network message handling
authorEddie <dev@fun2be.me>
Tue, 2 Jun 2015 16:08:49 +0000 (17:08 +0100)
committerEddie <dev@fun2be.me>
Tue, 2 Jun 2015 16:08:49 +0000 (17:08 +0100)
src/uk/ac/ntu/n0521366/wsyd/server/ServerSocial.java

index 673ef46..caa65b4 100644 (file)
@@ -50,12 +50,18 @@ import java.io.FileNotFoundException;
 import java.net.InetSocketAddress;
 import java.net.SocketException;
 import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Set;
 import java.util.logging.LogRecord;
 import javax.swing.Timer;
 import uk.ac.ntu.n0521366.wsyd.libs.WSYD_Member;
 import uk.ac.ntu.n0521366.wsyd.libs.WSYD_Member_Comparator_UserID;
+import uk.ac.ntu.n0521366.wsyd.libs.message.MessageLogin;
+import uk.ac.ntu.n0521366.wsyd.libs.message.MessageMemberState;
 import uk.ac.ntu.n0521366.wsyd.libs.message.MessagePresence;
 import uk.ac.ntu.n0521366.wsyd.libs.message.MessageServerControl;
+import uk.ac.ntu.n0521366.wsyd.libs.net.ConnectionEstablishedEvent;
+import uk.ac.ntu.n0521366.wsyd.libs.net.ConnectionEstablishedEventListener;
 import uk.ac.ntu.n0521366.wsyd.libs.net.Network;
 import uk.ac.ntu.n0521366.wsyd.libs.net.NetworkMessage;
 import uk.ac.ntu.n0521366.wsyd.libs.net.NetworkMessageEvent;
@@ -75,7 +81,7 @@ import uk.ac.ntu.n0521366.wsyd.libs.net.ServiceAddressMap.LastSeenHost;
  *
  * @author TJ <hacker@iam.tj>
  */
-public final class ServerSocial implements NetworkMessageEventListener {
+public final class ServerSocial implements NetworkMessageEventListener, ConnectionEstablishedEventListener {
     /**
      * Persistent storage in file-system when server exits.
      */
@@ -164,15 +170,20 @@ public final class ServerSocial implements NetworkMessageEventListener {
     {
         _multicastAdvertiserSA = new WSYD_SocketAddress(Network.MULTICAST_IP, Network.PORTS_MULTICAST_DISCOVERY, WSYD_SocketAddress.Protocol.UDP);
         _multicastService = new NetworkServerUDPMulticast(_multicastAdvertiserSA, _title + "MC", _serviceToAddressMap, LOGGER);
-        _multicastService.addNetworkMessageEventListener(this, "Neighbour");
+        _multicastService.getEventManager().addNetworkMessageEventListener(this, "Neighbour");
         _multicastService.execute();
         _serviceToAddressMap.put("all", new LastSeenHost(new InetSocketAddress(Network.MULTICAST_IP, Network.PORTS_MULTICAST_DISCOVERY), LastSeenHost.STATE.STATIC));
         
         _udpControlServiceSA = new WSYD_SocketAddress(Network.IPv4_WILDCARD, Network.PORTS_EPHEMERAL, WSYD_SocketAddress.Protocol.UDP);
         _udpControlService = new NetworkServerUDP(_udpControlServiceSA, _title + "Control", _serviceToAddressMap, LOGGER);
-        _udpControlService.addNetworkMessageEventListener(this, "Control");
+        _udpControlService.getEventManager().addNetworkMessageEventListener(this, "Control");
         _udpControlService.execute();
         
+        _tcpListeningServiceSA = new WSYD_SocketAddress(Network.IPv4_WILDCARD, Network.PORTS_SERVER_SOCIAL, WSYD_SocketAddress.Protocol.TCP);
+        _tcpListeningService = new NetworkServerTCP(_tcpListeningServiceSA, _title + "Listener", _serviceToAddressMap, _tcpStreamManager, LOGGER);
+        _tcpListeningService.addConnectionEstablisedEventListener(this);
+        _tcpListeningService.execute();
+        
         ActionListener servicesAnnounceActionListener = new ActionListener() {
             /**
              * Activated by timer events to send multi-cast neighbour announcements and other regular notifications.
@@ -186,7 +197,6 @@ public final class ServerSocial implements NetworkMessageEventListener {
                 NetworkMessage nm = NetworkMessage.createNetworkMessage("Neighbour", "all", mp);
                 nm.setSender(_title + "MC");
                 _multicastService.queueMessage(nm);
-                LOGGER.log(Level.INFO, "Neighbour advert");
 
                 // Notify ServerManagement of the Social Server Control service
                 String target = "ServerManagementControl";
@@ -207,6 +217,7 @@ public final class ServerSocial implements NetworkMessageEventListener {
                 ArrayList<String> servicesRemoved = _serviceToAddressMap.cleanServiceAddressMap(5000);
                 for (String service: servicesRemoved) {
                     // FIXME: does the process care if hosts have been removed? if not, remove this array iteration
+                    // TODO: If user client gone, remove from _membersOnline
                     switch (service) {
                     }
                 }
@@ -424,22 +435,63 @@ public final class ServerSocial implements NetworkMessageEventListener {
     @Override
     public void NetworkMessageReceived(NetworkMessageEvent event)
     {
+        System.err.println("NetworkMessage received");
         //TODO: NetworkMessageReceived: Handle Messages
         NetworkMessage nm = event.getNetworkMessage();
         if (nm == null)
             return;
         //Exit or Restart?
         System.err.println("Packet Received for intent " + nm.getIntent());
-        if ("Control".equals(nm.getIntent()))
-        {
-            String type = nm.getMessage().getMessageType();
-            if (type.equals(MessageServerControl.getType())) { // ServerControl
-                if ("ServerManagement".equals(nm.getSender())) {
-                    MessageServerControl mp = (MessageServerControl)nm.getMessage();
-                    if (mp.exitReq == MessageServerControl.EXIT.YES) ServerSocial.exitRequested = true;
-                    if (mp.restartReq == MessageServerControl.RESTART.YES) ServerSocial.restartRequested = true;
+        String type = nm.getMessage().getMessageType();
+        switch (nm.getIntent()) {
+            case "Control":
+                if (type.equals(MessageServerControl.getType())) { // ServerControl
+                    if ("ServerManagement".equals(nm.getSender())) {
+                        MessageServerControl mp = (MessageServerControl)nm.getMessage();
+                        if (mp.exitReq == MessageServerControl.EXIT.YES) ServerSocial.exitRequested = true;
+                        if (mp.restartReq == MessageServerControl.RESTART.YES) ServerSocial.restartRequested = true;
+                    }
                 }
-            }
+                break;
+            case "Login":
+                if (type.equals(MessageLogin.getType())) {
+                    MessageLogin ml = (MessageLogin)nm.getMessage();
+                    
+                    Set<Map.Entry<Long, WSYD_Member>> tempSet = _members.entrySet();
+                    Iterator<Map.Entry<Long, WSYD_Member>> tempIter = tempSet.iterator();
+                    while (tempIter.hasNext()) {
+                        Map.Entry<Long, WSYD_Member> element = tempIter.next();
+                        if (element.getValue()._userName.equals(ml._uName) && element.getValue()._password.equals(ml._uPass)) {
+                            ml._userID = element.getKey();
+                            ml._loggedIn = true;
+                            _tcpStreamManager.updateKey(nm.getKey(), element.getKey()); // replace temp key in stream manager
+                            _membersOnline.add(element.getKey()); // make the member online
+                        }
+                    }
+                    _tcpStreamManager._tcpStreams.get(nm.getKey()).write(nm);
+                }
+        }
+        
+    }
+    
+    private void notifyMemberPrescence(long userID, boolean state) {
+        NetworkMessage message = new NetworkMessage("MemberNotification", null, new MessageMemberState(userID, state));
+        for (long ID : _membersOnline) {
+            _tcpStreamManager._tcpStreams.get(ID).write(message);
+        }
+    }
+    
+    private void memberOnline (long userID) {
+        if (!_membersOnline.contains(userID)) {
+            notifyMemberPrescence(userID, true);
+            _membersOnline.add(userID);
+        }
+    }
+    
+    private void memberOffline (long userID) {
+        if (_membersOnline.contains(userID)) {
+            _membersOnline.remove(userID);
+            notifyMemberPrescence(userID, false);
         }
     }
 
@@ -459,6 +511,12 @@ public final class ServerSocial implements NetworkMessageEventListener {
             }
         }
     }
+
+    @Override
+    public void connectionEstablished(ConnectionEstablishedEvent event) {
+        System.err.println("connectionEstablished()");
+        event.getStream().getEventManager().addNetworkMessageEventListener(this);
+    }
 }