2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef DOMWebSocket_h
32 #define DOMWebSocket_h
34 #include "bindings/core/v8/ScriptWrappable.h"
35 #include "core/dom/ActiveDOMObject.h"
36 #include "core/events/EventListener.h"
37 #include "core/events/EventTarget.h"
38 #include "modules/EventTargetModules.h"
39 #include "modules/ModulesExport.h"
40 #include "modules/websockets/WebSocketChannel.h"
41 #include "modules/websockets/WebSocketChannelClient.h"
42 #include "platform/Timer.h"
43 #include "platform/heap/Handle.h"
44 #include "platform/weborigin/KURL.h"
45 #include "wtf/Deque.h"
46 #include "wtf/Forward.h"
47 #include "wtf/PassRefPtr.h"
48 #include "wtf/RefPtr.h"
49 #include "wtf/text/WTFString.h"
56 class DOMArrayBufferView
;
58 class ExecutionContext
;
59 class StringOrStringSequence
;
61 class MODULES_EXPORT DOMWebSocket
: public RefCountedGarbageCollectedEventTargetWithInlineData
<DOMWebSocket
>, public ActiveDOMObject
, public WebSocketChannelClient
{
62 REFCOUNTED_GARBAGE_COLLECTED_EVENT_TARGET(DOMWebSocket
);
63 DEFINE_WRAPPERTYPEINFO();
64 USING_GARBAGE_COLLECTED_MIXIN(DOMWebSocket
);
66 static const char* subprotocolSeperator();
67 // DOMWebSocket instances must be used with a wrapper since this class's
68 // lifetime management is designed assuming the V8 holds a ref on it while
69 // hasPendingActivity() returns true.
70 static DOMWebSocket
* create(ExecutionContext
*, const String
& url
, ExceptionState
&);
71 static DOMWebSocket
* create(ExecutionContext
*, const String
& url
, const StringOrStringSequence
& protocols
, ExceptionState
&);
72 ~DOMWebSocket() override
;
81 void connect(const String
& url
, const Vector
<String
>& protocols
, ExceptionState
&);
83 void send(const String
& message
, ExceptionState
&);
84 void send(DOMArrayBuffer
*, ExceptionState
&);
85 void send(DOMArrayBufferView
*, ExceptionState
&);
86 void send(Blob
*, ExceptionState
&);
88 // To distinguish close method call with the code parameter from one
89 // without, we have these three signatures. Use of
90 // Optional=DefaultIsUndefined in the IDL file doesn't help for now since
91 // it's bound to a value of 0 which is indistinguishable from the case 0
92 // is passed as code parameter.
93 void close(unsigned short code
, const String
& reason
, ExceptionState
&);
94 void close(ExceptionState
&);
95 void close(unsigned short code
, ExceptionState
&);
97 const KURL
& url() const;
98 State
readyState() const;
99 unsigned bufferedAmount() const;
101 String
protocol() const;
102 String
extensions() const;
104 String
binaryType() const;
105 void setBinaryType(const String
&);
107 DEFINE_ATTRIBUTE_EVENT_LISTENER(open
);
108 DEFINE_ATTRIBUTE_EVENT_LISTENER(message
);
109 DEFINE_ATTRIBUTE_EVENT_LISTENER(error
);
110 DEFINE_ATTRIBUTE_EVENT_LISTENER(close
);
112 // EventTarget functions.
113 const AtomicString
& interfaceName() const override
;
114 ExecutionContext
* executionContext() const override
;
116 // ActiveDOMObject functions.
117 void contextDestroyed() override
;
118 // Prevent this instance from being collected while it's not in CLOSED
120 bool hasPendingActivity() const override
;
121 void suspend() override
;
122 void resume() override
;
123 void stop() override
;
125 // WebSocketChannelClient functions.
126 void didConnect(const String
& subprotocol
, const String
& extensions
) override
;
127 void didReceiveTextMessage(const String
& message
) override
;
128 void didReceiveBinaryMessage(PassOwnPtr
<Vector
<char>>) override
;
129 void didError() override
;
130 void didConsumeBufferedAmount(uint64_t) override
;
131 void didStartClosingHandshake() override
;
132 void didClose(ClosingHandshakeCompletionStatus
, unsigned short code
, const String
& reason
) override
;
134 DECLARE_VIRTUAL_TRACE();
136 static bool isValidSubprotocolString(const String
&);
139 explicit DOMWebSocket(ExecutionContext
*);
142 // FIXME: This should inherit blink::EventQueue.
143 class EventQueue final
: public GarbageCollectedFinalized
<EventQueue
> {
145 static EventQueue
* create(EventTarget
* target
)
147 return new EventQueue(target
);
151 // Dispatches the event if this queue is active.
152 // Queues the event if this queue is suspended.
153 // Does nothing otherwise.
154 void dispatch(PassRefPtrWillBeRawPtr
<Event
> /* event */);
156 bool isEmpty() const;
171 explicit EventQueue(EventTarget
*);
173 // Dispatches queued events if this queue is active.
174 // Does nothing otherwise.
175 void dispatchQueuedEvents();
176 void resumeTimerFired(Timer
<EventQueue
>*);
179 RawPtrWillBeMember
<EventTarget
> m_target
;
180 WillBeHeapDeque
<RefPtrWillBeMember
<Event
>> m_events
;
181 Timer
<EventQueue
> m_resumeTimer
;
184 enum WebSocketSendType
{
185 WebSocketSendTypeString
,
186 WebSocketSendTypeArrayBuffer
,
187 WebSocketSendTypeArrayBufferView
,
188 WebSocketSendTypeBlob
,
189 WebSocketSendTypeMax
,
192 enum WebSocketReceiveType
{
193 WebSocketReceiveTypeString
,
194 WebSocketReceiveTypeArrayBuffer
,
195 WebSocketReceiveTypeBlob
,
196 WebSocketReceiveTypeMax
,
199 // This function is virtual for unittests.
200 // FIXME: Move WebSocketChannel::create here.
201 virtual WebSocketChannel
* createChannel(ExecutionContext
* context
, WebSocketChannelClient
* client
)
203 return WebSocketChannel::create(context
, client
);
206 // Adds a console message with JSMessageSource and ErrorMessageLevel.
207 void logError(const String
& message
);
209 // Handle the JavaScript close method call. close() methods on this class
210 // are just for determining if the optional code argument is supplied or
212 void closeInternal(int, const String
&, ExceptionState
&);
214 // Updates m_bufferedAmountAfterClose given the amount of data passed to
215 // send() method after the state changed to CLOSING or CLOSED.
216 void updateBufferedAmountAfterClose(uint64_t);
217 void reflectBufferedAmountConsumption(Timer
<DOMWebSocket
>*);
219 void releaseChannel();
223 BinaryTypeArrayBuffer
226 Member
<WebSocketChannel
> m_channel
;
230 uint64_t m_bufferedAmount
;
231 // The consumed buffered amount that will be reflected to m_bufferedAmount
232 // later. It will be cleared once reflected.
233 uint64_t m_consumedBufferedAmount
;
234 uint64_t m_bufferedAmountAfterClose
;
235 BinaryType m_binaryType
;
236 // The subprotocol the server selected.
237 String m_subprotocol
;
240 Member
<EventQueue
> m_eventQueue
;
241 Timer
<DOMWebSocket
> m_bufferedAmountConsumeTimer
;
246 #endif // DOMWebSocket_h