1//
2//  ========================================================================
3//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4//  ------------------------------------------------------------------------
5//  All rights reserved. This program and the accompanying materials
6//  are made available under the terms of the Eclipse Public License v1.0
7//  and Apache License v2.0 which accompanies this distribution.
8//
9//      The Eclipse Public License is available at
10//      http://www.eclipse.org/legal/epl-v10.html
11//
12//      The Apache License v2.0 is available at
13//      http://www.opensource.org/licenses/apache2.0.php
14//
15//  You may elect to redistribute this code under either of these licenses.
16//  ========================================================================
17//
18
19package org.eclipse.jetty.websocket;
20
21import java.io.IOException;
22
23/**
24 * WebSocket Interface.
25 * <p>
26 * This interface provides the signature for a server-side end point of a websocket connection.
27 * The Interface has several nested interfaces, for each type of message that may be received.
28 */
29public interface WebSocket
30{
31    /**
32     * Called when a new websocket connection is accepted.
33     * @param connection The Connection object to use to send messages.
34     */
35    void onOpen(Connection connection);
36
37    /**
38     * Called when an established websocket connection closes
39     * @param closeCode
40     * @param message
41     */
42    void onClose(int closeCode, String message);
43
44    /**
45     * A nested WebSocket interface for receiving text messages
46     */
47    interface OnTextMessage extends WebSocket
48    {
49        /**
50         * Called with a complete text message when all fragments have been received.
51         * The maximum size of text message that may be aggregated from multiple frames is set with {@link Connection#setMaxTextMessageSize(int)}.
52         * @param data The message
53         */
54        void onMessage(String data);
55    }
56
57    /**
58     * A nested WebSocket interface for receiving binary messages
59     */
60    interface OnBinaryMessage extends WebSocket
61    {
62        /**
63         * Called with a complete binary message when all fragments have been received.
64         * The maximum size of binary message that may be aggregated from multiple frames is set with {@link Connection#setMaxBinaryMessageSize(int)}.
65         * @param data
66         * @param offset
67         * @param length
68         */
69        void onMessage(byte[] data, int offset, int length);
70    }
71
72    /**
73     * A nested WebSocket interface for receiving control messages
74     */
75    interface OnControl extends WebSocket
76    {
77        /**
78         * Called when a control message has been received.
79         * @param controlCode
80         * @param data
81         * @param offset
82         * @param length
83         * @return true if this call has completely handled the control message and no further processing is needed.
84         */
85        boolean onControl(byte controlCode,byte[] data, int offset, int length);
86    }
87
88    /**
89     * A nested WebSocket interface for receiving any websocket frame
90     */
91    interface OnFrame extends WebSocket
92    {
93        /**
94         * Called when any websocket frame is received.
95         * @param flags
96         * @param opcode
97         * @param data
98         * @param offset
99         * @param length
100         * @return true if this call has completely handled the frame and no further processing is needed (including aggregation and/or message delivery)
101         */
102        boolean onFrame(byte flags,byte opcode,byte[] data, int offset, int length);
103
104        void onHandshake(FrameConnection connection);
105    }
106
107    /**
108     * A  Connection interface is passed to a WebSocket instance via the {@link WebSocket#onOpen(Connection)} to
109     * give the application access to the specifics of the current connection.   This includes methods
110     * for sending frames and messages as well as methods for interpreting the flags and opcodes of the connection.
111     */
112    public interface Connection
113    {
114        String getProtocol();
115        void sendMessage(String data) throws IOException;
116        void sendMessage(byte[] data, int offset, int length) throws IOException;
117
118        /**
119         * @deprecated Use {@link #close()}
120         */
121        void disconnect();
122
123        /**
124         * Close the connection with normal close code.
125         */
126        void close();
127
128        /** Close the connection with specific closeCode and message.
129         * @param closeCode The close code to send, or -1 for no close code
130         * @param message The message to send or null for no message
131         */
132        void close(int closeCode,String message);
133
134        boolean isOpen();
135
136        /**
137         * @param ms The time in ms that the connection can be idle before closing
138         */
139        void setMaxIdleTime(int ms);
140
141        /**
142         * @param size size<0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters
143         */
144        void setMaxTextMessageSize(int size);
145
146        /**
147         * @param size size<0 no aggregation of binary frames, >=0 size of binary frame aggregation buffer
148         */
149        void setMaxBinaryMessageSize(int size);
150
151        /**
152         * @return The time in ms that the connection can be idle before closing
153         */
154        int getMaxIdleTime();
155
156        /**
157         * Size in characters of the maximum text message to be received
158         * @return size <0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters
159         */
160        int getMaxTextMessageSize();
161
162        /**
163         * Size in bytes of the maximum binary message to be received
164         * @return size <0 no aggregation of binary frames, >=0 size of binary frame aggregation buffer
165         */
166        int getMaxBinaryMessageSize();
167    }
168
169    /**
170     * Frame Level Connection
171     * <p>The Connection interface at the level of sending/receiving frames rather than messages.
172     * Also contains methods to decode/generate flags and opcodes without using constants, so that
173     * code can be written to work with multiple drafts of the protocol.
174     *
175     */
176    public interface FrameConnection extends Connection
177    {
178        /**
179         * @return The opcode of a binary message
180         */
181        byte binaryOpcode();
182
183        /**
184         * @return The opcode of a text message
185         */
186        byte textOpcode();
187
188        /**
189         * @return The opcode of a continuation frame
190         */
191        byte continuationOpcode();
192
193        /**
194         * @return Mask for the FIN bit.
195         */
196        byte finMask();
197
198        /** Set if frames larger than the frame buffer are handled with local fragmentations
199         * @param allowFragmentation
200         */
201        void setAllowFrameFragmentation(boolean allowFragmentation);
202
203        /**
204         * @param flags The flags bytes of a frame
205         * @return True of the flags indicate a final frame.
206         */
207        boolean isMessageComplete(byte flags);
208
209        /**
210         * @param opcode
211         * @return True if the opcode is for a control frame
212         */
213        boolean isControl(byte opcode);
214
215        /**
216         * @param opcode
217         * @return True if the opcode is for a text frame
218         */
219        boolean isText(byte opcode);
220
221        /**
222         * @param opcode
223         * @return True if the opcode is for a binary frame
224         */
225        boolean isBinary(byte opcode);
226
227        /**
228         * @param opcode
229         * @return True if the opcode is for a continuation frame
230         */
231        boolean isContinuation(byte opcode);
232
233        /**
234         * @param opcode
235         * @return True if the opcode is a close control
236         */
237        boolean isClose(byte opcode);
238
239        /**
240         * @param opcode
241         * @return True if the opcode is a ping control
242         */
243        boolean isPing(byte opcode);
244
245        /**
246         * @param opcode
247         * @return True if the opcode is a pong control
248         */
249        boolean isPong(byte opcode);
250
251        /**
252         * @return True if frames larger than the frame buffer are fragmented.
253         */
254        boolean isAllowFrameFragmentation();
255
256        /** Send a control frame
257         * @param control
258         * @param data
259         * @param offset
260         * @param length
261         * @throws IOException
262         */
263        void sendControl(byte control,byte[] data, int offset, int length) throws IOException;
264
265        /** Send an arbitrary frame
266         * @param flags
267         * @param opcode
268         * @param data
269         * @param offset
270         * @param length
271         * @throws IOException
272         */
273        void sendFrame(byte flags,byte opcode,byte[] data, int offset, int length) throws IOException;
274    }
275}
276