Skip to content

Commit e40ce28

Browse files
author
Vitalii Cherkashyn
authored
web socket
1 parent 71f9266 commit e40ce28

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed

websocket/websocket.md

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
## servlet
2+
```java
3+
4+
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
5+
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
6+
7+
import javax.servlet.annotation.WebServlet;
8+
9+
@WebServlet(name = "Ref Event Websocket Servlet", urlPatterns = { "/ref-gen-event" })
10+
public class RefEventSocketServlet extends WebSocketServlet {
11+
12+
@Override
13+
public void configure(WebSocketServletFactory factory) {
14+
factory.getPolicy().setIdleTimeout(60 * 60 * 1000); // one hour
15+
factory.register(RefEventSocketServletHandler.class);
16+
}
17+
}
18+
19+
20+
```
21+
22+
## event handler
23+
```java
24+
import org.codehaus.jackson.map.ObjectMapper;
25+
import org.eclipse.jetty.websocket.api.Session;
26+
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
27+
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
28+
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
29+
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
30+
31+
import java.io.IOException;
32+
import java.util.*;
33+
import java.util.stream.Collectors;
34+
35+
/**
36+
* This is a WebSocket to keep track of started host ref generation Jobs.
37+
* The parameters for the connection are the username followed by the time when the generation was triggered.
38+
* After the connection was created, the frontend will send the list of sessionIds to trigger the host ref gen
39+
* for. A message will be send to the frontend after all jobs are finished.
40+
*/
41+
@WebSocket
42+
public class RefEventSocketServletHandler implements Loggable {
43+
44+
...
45+
46+
private ExportServiceImpl service;
47+
48+
public RefDataGenEventSocketHandler() {
49+
groundTruthExportService = ExportServiceImpl.getInstance();
50+
}
51+
52+
@OnWebSocketConnect
53+
public void onConnect(Session session) {
54+
try {
55+
// read parameters
56+
getConnectionParameters(session);
57+
58+
session.getRemote().sendString("Connected to WebSocket with Username: " +
59+
username + " and startedTime: " + startedTime);
60+
} catch (IOException e) {
61+
getLogger().warn("IO Exception during onConnect handling");
62+
}
63+
}
64+
65+
@OnWebSocketMessage
66+
public void onMessage(Session session, String message) {
67+
ObjectMapper mapper = new ObjectMapper();
68+
List<String> sessionIds;
69+
try {
70+
sessionIds = mapper.readValue(message, List.class);
71+
} catch (IOException e) {
72+
String errorMessage = "An error occurred while trying to parse the sessionId list! The connection will be closed.";
73+
getLogger().warn(errorMessage);
74+
try {
75+
session.getRemote().sendString(errorMessage);
76+
} catch (IOException ex) {
77+
getLogger().warn("IO Exception during onMessage handling");
78+
}
79+
session.close();
80+
return;
81+
}
82+
83+
String returnValue = someOperation(jobs);
84+
if (returnValue.isEmpty()) {
85+
try {
86+
session.getRemote().sendString(ERROR_GEN_PREFIX +
87+
"An error occurred ");
88+
} catch (IOException e) {
89+
getLogger().warn("IO Exception during onMessage handling");
90+
}
91+
} else {
92+
try {
93+
session.getRemote().sendString(returnValue);
94+
} catch (IOException e) {
95+
getLogger().warn("IO Exception during onMessage handling");
96+
}
97+
}
98+
}
99+
100+
@OnWebSocketClose
101+
public void onClose(int statusCode, String reason) {}
102+
103+
private void getConnectionParameters(Session session) {
104+
Map<String, List<String>> parameterMap = session.getUpgradeRequest().getParameterMap();
105+
this.username = parameterMap.get(USER_NAME_PARAMETER).get(0);
106+
this.startedTime = parameterMap.get(STARTED_TIME_PARAMETER).get(0);
107+
}
108+
109+
}
110+
```
111+
112+
## register handler
113+
```java
114+
115+
import org.eclipse.jetty.server.Server;
116+
import org.eclipse.jetty.server.handler.HandlerCollection;
117+
import org.eclipse.jetty.servlet.DefaultServlet;
118+
import org.eclipse.jetty.servlet.ServletContextHandler;
119+
import org.eclipse.jetty.servlet.ServletHolder;
120+
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
121+
import org.glassfish.jersey.server.ResourceConfig;
122+
import org.glassfish.jersey.servlet.ServletContainer;
123+
import java.net.URI;
124+
import java.net.URISyntaxException;
125+
import java.util.Arrays;
126+
127+
/**
128+
* Start SSL-secured HTTP test server.
129+
*/
130+
public void startNew() {
131+
this.server = createServer(options);
132+
ServletContextHandler ctx = new ServletContextHandler(ServletContextHandler.SESSIONS);
133+
ServletContextHandler ctxSwagger = new ServletContextHandler(ServletContextHandler.SESSIONS);
134+
135+
final String uriPathRestServices = addJerseyServlet(ctx);
136+
137+
addWebSocketToContext(ctx, RefDataGenEventSocketServlet.class, REF_DATA_GEN_WEBSOCKET_PATH);
138+
addPrometheusServletToContext(ctx);
139+
140+
HandlerCollection collection = new HandlerCollection();
141+
collection.addHandler(ctxSwagger);
142+
collection.addHandler(ctx);
143+
addSwaggerServletHolder(ctxSwagger);
144+
server.setHandler(collection);
145+
try {
146+
getLogger().info("starting api server");
147+
server.start();
148+
} catch (Exception e) {
149+
throw new IllegalArgumentException("could not start api rest server", e);
150+
}
151+
this.baseURI = buildBaseURI(options, uriPathRestServices);
152+
getLogger().info("api server available at {}", baseURI);
153+
Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
154+
}
155+
156+
private static Server createServer(DataApiServerOptions options) {
157+
Loggable.getLogger(DataApiServerManager.class).info("creating data api server at port {}", options.getServerPort());
158+
return new Server(options.getServerPort());
159+
}
160+
161+
162+
private void addSwaggerServletHolder(ServletContextHandler ctx) {
163+
ctx.setContextPath("/swagger");
164+
// Setup Swagger-UI static resources
165+
String resourceBasePath = getClass().getResource("/webapp").toExternalForm();
166+
ctx.setWelcomeFiles(new String[]{"index.html"});
167+
ctx.setResourceBase(resourceBasePath);
168+
ctx.addServlet(new ServletHolder(new DefaultServlet()), "/*");
169+
}
170+
171+
private static final String SERVLET_CONTAINER_NAME = "JerseyREST";
172+
private static final String SERVLET_CONTAINER_PATH = "/v1/";
173+
private static final String SESSION_PREVIEW_WEBSOCKET_PATH = "/data-api-ws/session-preview/*";
174+
private static final String REF_DATA_GEN_WEBSOCKET_PATH = "/data-api-ws/ref-data/*";
175+
176+
private String addJerseyServlet(ServletContextHandler ctx) {
177+
ServletHolder servlet = new ServletHolder(new ServletContainer(resourceConfig));
178+
servlet.setName(SERVLET_CONTAINER_NAME);
179+
servlet.setInitOrder(1);
180+
servlet.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true");
181+
ctx.addServlet(servlet, SERVLET_CONTAINER_PATH + "*");
182+
return SERVLET_CONTAINER_PATH;
183+
}
184+
185+
private void addWebSocketToContext(
186+
ServletContextHandler ctx,
187+
Class<? extends WebSocketServlet> eventSocketServletClass,
188+
String pathSpec) {
189+
ctx.addServlet(eventSocketServletClass, pathSpec);
190+
}
191+
192+
private void addPrometheusServletToContext(ServletContextHandler ctx) {
193+
new PrometheusServletToContext().addToContext(ctx);
194+
}
195+
196+
public static String getKeyStoreResourceName() {
197+
return KEYSTORE_SERVER_FILE_IN_CLASS_PATH;
198+
}
199+
200+
public static String getKeyStoreKey() {
201+
return KEYSTORE_SERVER_KEY;
202+
}
203+
204+
```

0 commit comments

Comments
 (0)