1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.client.io;
20
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.net.SocketAddress;
24 import java.net.URI;
25 import java.nio.channels.SocketChannel;
26 import java.util.Locale;
27
28 import org.eclipse.jetty.util.component.ContainerLifeCycle;
29 import org.eclipse.jetty.util.log.Log;
30 import org.eclipse.jetty.util.log.Logger;
31 import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
32 import org.eclipse.jetty.websocket.client.WebSocketClient;
33 import org.eclipse.jetty.websocket.common.events.EventDriver;
34
35
36
37
38
39 public class ConnectionManager extends ContainerLifeCycle
40 {
41 private class PhysicalConnect extends ConnectPromise
42 {
43 private SocketAddress bindAddress;
44
45 public PhysicalConnect(WebSocketClient client, EventDriver driver, ClientUpgradeRequest request)
46 {
47 super(client,driver,request);
48 this.bindAddress = client.getBindAddress();
49 }
50
51 @Override
52 public void run()
53 {
54 SocketChannel channel = null;
55 try
56 {
57 channel = SocketChannel.open();
58 if (bindAddress != null)
59 {
60 channel.bind(bindAddress);
61 }
62
63 URI wsUri = getRequest().getRequestURI();
64
65 channel.socket().setTcpNoDelay(true);
66 channel.configureBlocking(false);
67
68 InetSocketAddress address = toSocketAddress(wsUri);
69
70 if (channel.connect(address))
71 {
72 getSelector().accept(channel, this);
73 }
74 else
75 {
76 getSelector().connect(channel, this);
77 }
78 }
79 catch (Throwable t)
80 {
81
82 if (channel != null)
83 {
84 try
85 {
86 channel.close();
87 }
88 catch (IOException ignore)
89 {
90 LOG.ignore(ignore);
91 }
92 }
93
94
95 failed(t);
96 }
97 }
98 }
99
100 private static final Logger LOG = Log.getLogger(ConnectionManager.class);
101
102 public static InetSocketAddress toSocketAddress(URI uri)
103 {
104 if (!uri.isAbsolute())
105 {
106 throw new IllegalArgumentException("Cannot get InetSocketAddress of non-absolute URIs");
107 }
108
109 int port = uri.getPort();
110 String scheme = uri.getScheme().toLowerCase(Locale.ENGLISH);
111 if ("ws".equals(scheme))
112 {
113 if (port == (-1))
114 {
115 port = 80;
116 }
117 }
118 else if ("wss".equals(scheme))
119 {
120 if (port == (-1))
121 {
122 port = 443;
123 }
124 }
125 else
126 {
127 throw new IllegalArgumentException("Only support ws:// and wss:// URIs");
128 }
129
130 return new InetSocketAddress(uri.getHost(),port);
131 }
132
133 private final WebSocketClient client;
134 private WebSocketClientSelectorManager selector;
135
136 public ConnectionManager(WebSocketClient client)
137 {
138 this.client = client;
139 }
140
141 public ConnectPromise connect(WebSocketClient client, EventDriver driver, ClientUpgradeRequest request)
142 {
143 return new PhysicalConnect(client,driver,request);
144 }
145
146 @Override
147 protected void doStart() throws Exception
148 {
149 selector = newWebSocketClientSelectorManager(client);
150 selector.setSslContextFactory(client.getSslContextFactory());
151 selector.setConnectTimeout(client.getConnectTimeout());
152 addBean(selector);
153
154 super.doStart();
155 }
156
157 @Override
158 protected void doStop() throws Exception
159 {
160 super.doStop();
161 removeBean(selector);
162 }
163
164 public WebSocketClientSelectorManager getSelector()
165 {
166 return selector;
167 }
168
169
170
171
172
173
174
175
176 protected WebSocketClientSelectorManager newWebSocketClientSelectorManager(WebSocketClient client)
177 {
178 return new WebSocketClientSelectorManager(client);
179 }
180 }