1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.common;
20
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.nio.ByteBuffer;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.Future;
26
27 import org.eclipse.jetty.util.BufferUtil;
28 import org.eclipse.jetty.util.log.Log;
29 import org.eclipse.jetty.util.log.Logger;
30 import org.eclipse.jetty.websocket.api.RemoteEndpoint;
31 import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
32 import org.eclipse.jetty.websocket.common.io.FutureWriteCallback;
33
34
35
36
37 public class WebSocketRemoteEndpoint implements RemoteEndpoint
38 {
39 private static final Logger LOG = Log.getLogger(WebSocketRemoteEndpoint.class);
40 public final LogicalConnection connection;
41 public final OutgoingFrames outgoing;
42
43 public WebSocketRemoteEndpoint(LogicalConnection connection, OutgoingFrames outgoing)
44 {
45 if (connection == null)
46 {
47 throw new IllegalArgumentException("LogicalConnection cannot be null");
48 }
49 this.connection = connection;
50 this.outgoing = outgoing;
51 }
52
53 private void blockingWrite(WebSocketFrame frame) throws IOException
54 {
55 Future<Void> fut = sendAsyncFrame(frame);
56 try
57 {
58 fut.get();
59 }
60 catch (ExecutionException e)
61 {
62 throw new IOException("Failed to write bytes",e.getCause());
63 }
64 catch (InterruptedException e)
65 {
66 throw new IOException("Failed to write bytes",e);
67 }
68 }
69
70 public InetSocketAddress getInetSocketAddress()
71 {
72 return connection.getRemoteAddress();
73 }
74
75
76
77
78
79
80
81
82 private Future<Void> sendAsyncFrame(WebSocketFrame frame)
83 {
84 FutureWriteCallback future = new FutureWriteCallback();
85 try
86 {
87 connection.getIOState().assertOutputOpen();
88 outgoing.outgoingFrame(frame,future);
89 }
90 catch (IOException e)
91 {
92 future.writeFailed(e);
93 }
94 return future;
95 }
96
97
98
99
100 @Override
101 public void sendBytes(ByteBuffer data) throws IOException
102 {
103 connection.getIOState().assertOutputOpen();
104 if (LOG.isDebugEnabled())
105 {
106 LOG.debug("sendBytes with {}",BufferUtil.toDetailString(data));
107 }
108 WebSocketFrame frame = WebSocketFrame.binary().setPayload(data);
109 blockingWrite(frame);
110 }
111
112 @Override
113 public Future<Void> sendBytesByFuture(ByteBuffer data)
114 {
115 if (LOG.isDebugEnabled())
116 {
117 LOG.debug("sendBytesByFuture with {}",BufferUtil.toDetailString(data));
118 }
119 WebSocketFrame frame = WebSocketFrame.binary().setPayload(data);
120 return sendAsyncFrame(frame);
121 }
122
123 @Override
124 public void sendPartialBytes(ByteBuffer fragment, boolean isLast) throws IOException
125 {
126 if (LOG.isDebugEnabled())
127 {
128 LOG.debug("sendPartialBytes({}, {})",BufferUtil.toDetailString(fragment),isLast);
129 }
130 WebSocketFrame frame = WebSocketFrame.binary().setPayload(fragment).setFin(isLast);
131 blockingWrite(frame);
132 }
133
134 @Override
135 public void sendPartialString(String fragment, boolean isLast) throws IOException
136 {
137 if (LOG.isDebugEnabled())
138 {
139 LOG.debug("sendPartialString({}, {})",fragment,isLast);
140 }
141 WebSocketFrame frame = WebSocketFrame.text(fragment).setFin(isLast);
142 blockingWrite(frame);
143 }
144
145 @Override
146 public void sendPing(ByteBuffer applicationData) throws IOException
147 {
148 if (LOG.isDebugEnabled())
149 {
150 LOG.debug("sendPing with {}",BufferUtil.toDetailString(applicationData));
151 }
152 WebSocketFrame frame = WebSocketFrame.ping().setPayload(applicationData);
153 blockingWrite(frame);
154 }
155
156 @Override
157 public void sendPong(ByteBuffer applicationData) throws IOException
158 {
159 if (LOG.isDebugEnabled())
160 {
161 LOG.debug("sendPong with {}",BufferUtil.toDetailString(applicationData));
162 }
163 WebSocketFrame frame = WebSocketFrame.pong().setPayload(applicationData);
164 blockingWrite(frame);
165 }
166
167 @Override
168 public void sendString(String text) throws IOException
169 {
170 WebSocketFrame frame = WebSocketFrame.text(text);
171 if (LOG.isDebugEnabled())
172 {
173 LOG.debug("sendString with {}",BufferUtil.toDetailString(frame.getPayload()));
174 }
175 blockingWrite(WebSocketFrame.text(text));
176 }
177
178 @Override
179 public Future<Void> sendStringByFuture(String text)
180 {
181 WebSocketFrame frame = WebSocketFrame.text(text);
182 if (LOG.isDebugEnabled())
183 {
184 LOG.debug("sendStringByFuture with {}",BufferUtil.toDetailString(frame.getPayload()));
185 }
186 return sendAsyncFrame(frame);
187 }
188 }