source: src/main/java/geniusweb/partiesserver/websocket/PartiesListSocket.java@ 1

Last change on this file since 1 was 1, checked in by bart, 5 years ago

Initial Release

File size: 4.4 KB
Line 
1package geniusweb.partiesserver.websocket;
2
3import java.io.IOException;
4import java.lang.management.ManagementFactory;
5import java.net.InetAddress;
6import java.net.URI;
7import java.net.URISyntaxException;
8import java.net.UnknownHostException;
9import java.util.LinkedList;
10import java.util.List;
11import java.util.Set;
12import java.util.logging.Level;
13
14import javax.management.MBeanServer;
15import javax.management.MalformedObjectNameException;
16import javax.management.ObjectName;
17import javax.management.Query;
18import javax.websocket.OnClose;
19import javax.websocket.OnError;
20import javax.websocket.OnOpen;
21import javax.websocket.Session;
22import javax.websocket.server.ServerEndpoint;
23
24import com.fasterxml.jackson.databind.ObjectMapper;
25
26import geniusweb.partiesserver.repository.AvailablePartiesRepo;
27import geniusweb.partiesserver.repository.AvailableParty;
28import geniusweb.partiesserver.repository.GeneralPartyInfo;
29import tudelft.utilities.listener.Listener;
30import tudelft.utilities.logging.ReportToLogger;
31import tudelft.utilities.logging.Reporter;
32
33/**
34 * Returns a websocket that communicates the list of currently available
35 * (runnable) parties. Every time something changes, a new list of parties is
36 * sent.
37 */
38@ServerEndpoint("/available")
39public class PartiesListSocket {
40
41 private static final String DEFAULT_ADDRESS = "localhost:8080";
42 private final Reporter log;
43 private Listener<String> changeListener; // final, but only initialized in
44 // startSession.
45 private Session session;
46 private AvailablePartiesRepo repo;
47 private SendBuffer outstream;
48
49 public PartiesListSocket() {
50 this(new ReportToLogger("partiesserver"));
51 }
52
53 public PartiesListSocket(Reporter reporter) {
54 this.log = reporter;
55 }
56
57 @OnOpen
58 public void start(Session session) throws IOException {
59 this.session = session;
60 this.outstream = new SendBuffer(session.getBasicRemote(), log);
61
62 repo = getRepo();
63 changeListener = new Listener<String>() {
64 @Override
65 public void notifyChange(String data) {
66 sendUpdatedParties();
67 }
68 };
69 repo.addListener(changeListener);
70
71 sendUpdatedParties();
72 }
73
74 /**
75 * Send the currently available parties to the client.
76 *
77 * @throws IOException
78 */
79 private void sendUpdatedParties() {
80 System.out.println("sending updated parties list1");
81 String ip = DEFAULT_ADDRESS; // default if something fails
82 try {
83 ip = getIpAddressAndPort() + "/" + getServerName();
84 } catch (MalformedObjectNameException | UnknownHostException e1) {
85 log.log(Level.SEVERE,
86 "Can't get proper server name and port, reverting to "
87 + DEFAULT_ADDRESS,
88 e1);
89 }
90 try {
91 List<GeneralPartyInfo> list = new LinkedList<>();
92 for (AvailableParty party : repo.list()) {
93 URI uri = new URI("http://" + ip + "/run/" + party.getName());
94 list.add(new GeneralPartyInfo(uri, party.getCapabilities(),
95 party.getDescription()));
96 }
97 String text = new ObjectMapper().writeValueAsString(list);
98 outstream.send(text);
99 } catch (IOException | URISyntaxException e) {
100 log.log(Level.SEVERE, "Bug sending updated parties list", e);
101 }
102 }
103
104 @OnClose
105 public void onClose() throws IOException {
106 repo.removeListener(changeListener);
107 outstream.stop();
108 }
109
110 @OnError
111 public void onError(Throwable t) throws Throwable {
112 if (t instanceof IOException && "Broken pipe".equals(t.getMessage())) {
113 log.log(Level.INFO, "Socket pipe broke:" + session);
114 } else {
115 log.log(Level.SEVERE,
116 "Tomcat reported an error on the connection:" + session, t);
117 }
118 }
119
120 /**
121 * FactoryMethod for testing
122 *
123 * @return RunningPartiesRepo
124 */
125 protected AvailablePartiesRepo getRepo() {
126 return AvailablePartiesRepo.instance();
127 }
128
129 /**
130 *
131 * @return name of our service, eg "profilesserver"
132 */
133 private String getServerName() {
134 // typically something like /profilesserver/websocket/liststream
135 // profilesserver is the name we're looking for
136 return session.getRequestURI().getPath().split("/")[1]; // drop leading
137 // '/'
138 }
139
140 private String getIpAddressAndPort()
141 throws UnknownHostException, MalformedObjectNameException {
142
143 MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
144
145 Set<ObjectName> objectNames = beanServer.queryNames(
146 new ObjectName("*:type=Connector,*"),
147 Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
148
149 String host = InetAddress.getLocalHost().getHostAddress();
150 String port = objectNames.iterator().next().getKeyProperty("port");
151
152 return host + ":" + port;
153
154 }
155
156}
Note: See TracBrowser for help on using the repository browser.