1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.jsr356.server;
20
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.concurrent.Executor;
24
25 import javax.websocket.DeploymentException;
26 import javax.websocket.Endpoint;
27 import javax.websocket.server.ServerEndpoint;
28 import javax.websocket.server.ServerEndpointConfig;
29
30 import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec;
31 import org.eclipse.jetty.util.log.Log;
32 import org.eclipse.jetty.util.log.Logger;
33 import org.eclipse.jetty.websocket.common.WebSocketSession;
34 import org.eclipse.jetty.websocket.common.events.EventDriverFactory;
35 import org.eclipse.jetty.websocket.jsr356.ClientContainer;
36 import org.eclipse.jetty.websocket.jsr356.JsrSessionFactory;
37 import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner;
38 import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance;
39 import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata;
40 import org.eclipse.jetty.websocket.server.MappedWebSocketCreator;
41 import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
42
43 public class ServerContainer extends ClientContainer implements javax.websocket.server.ServerContainer
44 {
45 private static final Logger LOG = Log.getLogger(ServerContainer.class);
46
47 private final MappedWebSocketCreator mappedCreator;
48 private final WebSocketServerFactory webSocketServerFactory;
49 private List<Class<?>> deferredEndpointClasses;
50 private List<ServerEndpointConfig> deferredEndpointConfigs;
51
52 public ServerContainer(MappedWebSocketCreator creator, WebSocketServerFactory factory, Executor executor)
53 {
54 super(factory);
55 this.mappedCreator = creator;
56 this.webSocketServerFactory = factory;
57 EventDriverFactory eventDriverFactory = this.webSocketServerFactory.getEventDriverFactory();
58 eventDriverFactory.addImplementation(new JsrServerEndpointImpl());
59 eventDriverFactory.addImplementation(new JsrServerExtendsEndpointImpl());
60 this.webSocketServerFactory.addSessionFactory(new JsrSessionFactory(this));
61 addBean(webSocketServerFactory);
62 }
63
64 public EndpointInstance newClientEndpointInstance(Object endpoint, ServerEndpointConfig config, String path)
65 {
66 EndpointMetadata metadata = getClientEndpointMetadata(endpoint.getClass(),config);
67 ServerEndpointConfig cec = config;
68 if (config == null)
69 {
70 if (metadata instanceof AnnotatedServerEndpointMetadata)
71 {
72 cec = ((AnnotatedServerEndpointMetadata)metadata).getConfig();
73 }
74 else
75 {
76 cec = new BasicServerEndpointConfig(this,endpoint.getClass(),path);
77 }
78 }
79 return new EndpointInstance(endpoint,cec,metadata);
80 }
81
82 @Override
83 public void addEndpoint(Class<?> endpointClass) throws DeploymentException
84 {
85 if (isStarted() || isStarting())
86 {
87 ServerEndpointMetadata metadata = getServerEndpointMetadata(endpointClass,null);
88 addEndpoint(metadata);
89 }
90 else
91 {
92 if (deferredEndpointClasses == null)
93 {
94 deferredEndpointClasses = new ArrayList<Class<?>>();
95 }
96 deferredEndpointClasses.add(endpointClass);
97 }
98 }
99
100 private void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException
101 {
102 JsrCreator creator = new JsrCreator(this,metadata,webSocketServerFactory.getExtensionFactory());
103 mappedCreator.addMapping(new UriTemplatePathSpec(metadata.getPath()),creator);
104 }
105
106 @Override
107 public void addEndpoint(ServerEndpointConfig config) throws DeploymentException
108 {
109 if (isStarted() || isStarting())
110 {
111 if (LOG.isDebugEnabled())
112 {
113 LOG.debug("addEndpoint({}) path={} endpoint={}",config,config.getPath(),config.getEndpointClass());
114 }
115 ServerEndpointMetadata metadata = getServerEndpointMetadata(config.getEndpointClass(),config);
116 addEndpoint(metadata);
117 }
118 else
119 {
120 if (deferredEndpointConfigs == null)
121 {
122 deferredEndpointConfigs = new ArrayList<ServerEndpointConfig>();
123 }
124 deferredEndpointConfigs.add(config);
125 }
126 }
127
128 @Override
129 protected void doStart() throws Exception
130 {
131
132 super.doStart();
133
134
135 if (deferredEndpointClasses != null)
136 {
137 for (Class<?> endpointClass : deferredEndpointClasses)
138 {
139 addEndpoint(endpointClass);
140 }
141 deferredEndpointClasses.clear();
142 }
143
144 if (deferredEndpointConfigs != null)
145 {
146 for (ServerEndpointConfig config : deferredEndpointConfigs)
147 {
148 addEndpoint(config);
149 }
150 deferredEndpointConfigs.clear();
151 }
152 }
153
154 public ServerEndpointMetadata getServerEndpointMetadata(final Class<?> endpoint, final ServerEndpointConfig config) throws DeploymentException
155 {
156 ServerEndpointMetadata metadata = null;
157
158 ServerEndpoint anno = endpoint.getAnnotation(ServerEndpoint.class);
159 if (anno != null)
160 {
161
162 AnnotatedServerEndpointMetadata ametadata = new AnnotatedServerEndpointMetadata(this,endpoint,config);
163 AnnotatedEndpointScanner<ServerEndpoint, ServerEndpointConfig> scanner = new AnnotatedEndpointScanner<>(ametadata);
164 metadata = ametadata;
165 scanner.scan();
166 }
167 else if (Endpoint.class.isAssignableFrom(endpoint))
168 {
169
170 @SuppressWarnings("unchecked")
171 Class<? extends Endpoint> eendpoint = (Class<? extends Endpoint>)endpoint;
172 metadata = new SimpleServerEndpointMetadata(eendpoint,config);
173 }
174 else
175 {
176 StringBuilder err = new StringBuilder();
177 err.append("Not a recognized websocket [");
178 err.append(endpoint.getName());
179 err.append("] does not extend @").append(ServerEndpoint.class.getName());
180 err.append(" or extend from ").append(Endpoint.class.getName());
181 throw new DeploymentException("Unable to identify as valid Endpoint: " + endpoint);
182 }
183
184 return metadata;
185 }
186
187 @Override
188 public long getDefaultAsyncSendTimeout()
189 {
190 return webSocketServerFactory.getPolicy().getAsyncWriteTimeout();
191 }
192
193 @Override
194 public int getDefaultMaxBinaryMessageBufferSize()
195 {
196 return webSocketServerFactory.getPolicy().getMaxBinaryMessageSize();
197 }
198
199 @Override
200 public long getDefaultMaxSessionIdleTimeout()
201 {
202 return webSocketServerFactory.getPolicy().getIdleTimeout();
203 }
204
205 @Override
206 public int getDefaultMaxTextMessageBufferSize()
207 {
208 return webSocketServerFactory.getPolicy().getMaxTextMessageSize();
209 }
210
211 @Override
212 public void setAsyncSendTimeout(long ms)
213 {
214 super.setAsyncSendTimeout(ms);
215 webSocketServerFactory.getPolicy().setAsyncWriteTimeout(ms);
216 }
217
218 @Override
219 public void setDefaultMaxBinaryMessageBufferSize(int max)
220 {
221 super.setDefaultMaxBinaryMessageBufferSize(max);
222
223 webSocketServerFactory.getPolicy().setMaxBinaryMessageSize(max);
224
225 webSocketServerFactory.getPolicy().setMaxBinaryMessageBufferSize(max);
226 }
227
228 @Override
229 public void setDefaultMaxSessionIdleTimeout(long ms)
230 {
231 super.setDefaultMaxSessionIdleTimeout(ms);
232 webSocketServerFactory.getPolicy().setIdleTimeout(ms);
233 }
234
235 @Override
236 public void setDefaultMaxTextMessageBufferSize(int max)
237 {
238 super.setDefaultMaxTextMessageBufferSize(max);
239
240 webSocketServerFactory.getPolicy().setMaxTextMessageSize(max);
241
242 webSocketServerFactory.getPolicy().setMaxTextMessageBufferSize(max);
243 }
244
245 @Override
246 public void onSessionClosed(WebSocketSession session)
247 {
248 webSocketServerFactory.onSessionClosed(session);
249 }
250
251 @Override
252 public void onSessionOpened(WebSocketSession session)
253 {
254 webSocketServerFactory.onSessionOpened(session);
255 }
256 }