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