diff --git a/index.html b/index.html index f2cf615..3aaa7d8 100644 --- a/index.html +++ b/index.html @@ -3,18 +3,18 @@
- This API provides interfaces to raw UDP sockets, TCP Client sockets and - TCP Server sockets. -
+ This API provides interfaces to raw UDP sockets, TCP Client sockets and + TCP Server sockets. +This specification is based the Streams API, [[!STREAMS]]. Note that the Streams API is work in progress and any changes made to Streams may - impact the TCP and UDP Socket API specification. However, it is the + impact the TCP and UDP Socket API specification. However, it is the editor's ambition to continously update the TCP and UDP API specification to be aligned with the latest version the Streams API.
-- This is a note on error handling. + This is a note on error handling.
- When using promises rejection reasons should always be instances of - the ECMAScript Error type such as DOMException or the built in - ECMAScript error types. See + When using promises rejection reasons should always be instances of + the ECMAScript Error type such as DOMException or the built in + ECMAScript error types. See Promise rejection reasons. In the TCP and UDP Socket API the error names defined in WebIDL Exceptions are used. If additional error names are needed an update to - Github WebIDL should be requested through a Pull Request. + Github WebIDL should be requested through a Pull Request.
-- This is a note on data types of TCP and UDP to send and receive. + This is a note on data types of TCP and UDP to send and receive.
- In the previous version of this API the send() method accepted the - following data types for the data to send: DOMString,Blob, ArrayBuffer - or ArrayBufferView. This was aligned with the send() method for + In the previous version of this API the send() method accepted the + following data types for the data to send: DOMString,Blob, ArrayBuffer + or ArrayBufferView. This was aligned with the send() method for Web Sockets. In this Streams API based version only ArrayBuffer is - accepted as type for data to send. The reason is that encoding issues - in a Streams based API should instead be handled by a transform + accepted as type for data to send. The reason is that encoding issues + in a Streams based API should instead be handled by a transform stream. -
- -- Use this API to send and receive data over the network using TCP or UDP. + Use this API to send and receive data over the network using TCP or UDP.
- +Examples of use cases for this API are:
@@ -225,44 +225,44 @@This specification defines conformance criteria that apply to a single - product: the user agent that implements the interfaces that +
This specification defines conformance criteria that apply to a single + product: the user agent that implements the interfaces that it contains.
- -Implementations that use ECMAScript to implement the APIs defined in this - specification MUST implement them in a manner consistent with the ECMAScript + +
Implementations that use ECMAScript to implement the APIs defined in this + specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]], as this specification uses that specification and terminology. -
- + +The term webapp refers to a Web application, i.e. an application implemented using Web technologies, and executing within - the context of a Web user agent, e.g. a Web browser or other + the context of a Web user agent, e.g. a Web browser or other Web runtime environment.
- +
- The Promise
- interface provides asynchronous access to the result of an operation
+ The Promise
+ interface provides asynchronous access to the result of an operation
that is ongoing, has yet to start, or has completed, as defined in
[[!ES6]].
This is a security and privacy sensitive API and a webapp must - have permission to use the API. The manner in which permission is given - or not varies depending on the type of web runtime environment in which + have permission to use the API. The manner in which permission is given + or not varies depending on the type of web runtime environment in which this API is implemented and could be based on:
The UDPPermission, TCPPermission and TCPServerPermission
- interfaces provides a method hasPermission
that retrieves
- the permission state for the requesting webapp and a method
+ interfaces provides a method hasPermission
that retrieves
+ the permission state for the requesting webapp and a method
requestPermission
that requests permission for the webapp
- to use the socket interface. If a webapp calls the contructor of a
+ to use the socket interface. If a webapp calls the contructor of a
socket interface for which it has not permission to access the
user agent MUST immediately throw DOMException
- "SecurityError"
.
+ "SecurityError"
.
- The idea behind the UDPPermission, TCPPermission and
- TCPServerPermission interfaces is to isolate the permission
- system from the socket interfaces specifications. The manner in which
- permission to use this API differs depending on the type of web runtime
- it is implemented in. For example, a web runtime for secure installed
- web applications may be able to open up this API so that no explicit
- user content is needed, while an implementation in a web browser may
+ The idea behind the UDPPermission, TCPPermission and
+ TCPServerPermission interfaces is to isolate the permission
+ system from the socket interfaces specifications. The manner in which
+ permission to use this API differs depending on the type of web runtime
+ it is implemented in. For example, a web runtime for secure installed
+ web applications may be able to open up this API so that no explicit
+ user content is needed, while an implementation in a web browser may
use a combination of web security mechanisms, such as secure transport
(https:), content security policies (CSP) and a signed manifest,
- and user consent to open up the API.
+ and user consent to open up the API.
The Permissions API,
which currently is an unofficial draft, is an API that allows a web
- application to be aware of the status of a given permission, to know
+ application to be aware of the status of a given permission, to know
whether it is granted, denied or if the user will be asked whether the
- permission should be granted or not. If this API gets consensus and
+ permission should be granted or not. If this API gets consensus and
becomes a W3C standard, and also is extended to support permission
- requests, it may be possible to replace the hasPermission
+ requests, it may be possible to replace the hasPermission
and requestPermission
methods in this specification with
- a reference to the Permission API.
+ a reference to the Permission API.
W3C has activities on security for web applications, see
Web Application Security Working Group
- and on trust and permissions, see
+ and on trust and permissions, see
Workshop on trust and permissions for Web applications 3–4 September
2014, Paris, France and
- Trust & Permissions Community Group.
+ Trust & Permissions Community Group.
- The CSP directive connect-src
- is used to restrict the allowed connection targets for XHR, Web Sockets
+ The CSP directive connect-src
+ is used to restrict the allowed connection targets for XHR, Web Sockets
and Server-Sent Events. It should be considered if connect-src
should be extended to support allowed remote peers for raw TCP and UDP
sockets as well. However, currently the allowed connection targets for connect-src
- are defined as a Source List
+ are defined as a Source List
and this assumes URI schemes. So, schemes for UDP and TCP, i.e. udp:
- and tcp:, might have to be defined. See address + port vs uri.
-
This interface exposes methods related to the permission to access the UDPSocket interface. Permission could be given based on user - consent, based on trust for the webapp, e.g. related to the - origin of it and verified through web security mechanisms such as - secure transport and signatures, based on previously granted or - denied permission explicitly for this webapp or a combination of + consent, based on trust for the webapp, e.g. related to the + origin of it and verified through web security mechanisms such as + secure transport and signatures, based on previously granted or + denied permission explicitly for this webapp or a combination of these mechanisms. -
- + +This method MUST run the following steps asynchronously:
udpPermissionPromise
,
- return it and run the remaining steps asynchronously.udpPermissionOptions
argument.udpPermissionPromise
with no arguments and abort the remaining steps.udpPermissionPromise
with TCPUDPPermissionState providing the permission
- state. This method MUST run the following steps asynchronously:
udpRequestPermissionPromise
,
- return it and run the remaining steps asynchronously.tcpRequestPermissionPromise
with DOMException "SecurityError"
and
abort the remaining steps.tcpRequestPermissionPromise
with DOMException "SecurityError"
and
- abort the remaining steps.udpRequestPermissionPromise
and abort the remaining
steps.udpRequestPermissionPromise
- and abort the remaining steps.udpRequestPermissionPromise
+ and abort the remaining steps.udpRequestPermissionPromise
- with DOMException "SecurityError"
. "SecurityError"
.
+
+
+
This interface exposes methods related to the permission to access the TCPSocket interface. Permission could be given based on user - consent, based on trust for the webapp, e.g. related to the - origin of it and verified through web security mechanisms such as - secure transport and signatures, based on previously granted or - denied permission explicitly for this webapp or a combination of + consent, based on trust for the webapp, e.g. related to the + origin of it and verified through web security mechanisms such as + secure transport and signatures, based on previously granted or + denied permission explicitly for this webapp or a combination of these mechanisms. -
- + +This method MUST run the following steps asynchronously:
tcpPermissionPromise
,
- return it and run the remaining steps asynchronously.tcpPermissionPromise
with TCPUDPPermissionState providing the permission
- state. This method MUST run the following steps asynchronously:
tcpRequestPermissionPromise
,
- return it and run the remaining steps asynchronously.tcpRequestPermissionPromise
with DOMException "SecurityError"
and
abort the remaining steps.tcpRequestPermissionPromise
and abort the remaining
steps.tcpRequestPermissionPromise
- and abort the remaining steps.tcpRequestPermissionPromise
+ and abort the remaining steps.tcpRequestPermissionPromise
- with DOMException "SecurityError"
. "SecurityError"
.
+
+
+
This interface exposes methods related to the permission to access - the TCPServerSocket interface. Permission could be given based - on user consent, based on trust for the webapp, e.g. related to - the origin of it and verified through web security mechanisms such as - secure transport and signatures, based on previously granted or - denied permission explicitly for this webapp or a combination of + the TCPServerSocket interface. Permission could be given based + on user consent, based on trust for the webapp, e.g. related to + the origin of it and verified through web security mechanisms such as + secure transport and signatures, based on previously granted or + denied permission explicitly for this webapp or a combination of these mechanisms. -
- + +This method MUST run the following steps asynchronously:
tcpServerPermissionPromise
,
- return it and run the remaining steps asynchronously.tcpServerPermissionOptions
argument.tcpServerPermissionPromise
with no arguments and abort the remaining steps.tcpServerPermissionPromise
with TCPUDPPermissionState providing the permission
- state. This method MUST run the following steps asynchronously:
tcpServerRequestPermissionPromise
,
- return it and run the remaining steps asynchronously.tcpServerRequestPermissionPromise
with DOMException "SecurityError"
and
- abort the remaining steps.tcpServerRequestPermissionPromise
and abort the
+ on a prearranged trust relationship or the user has already
+ granted permission explicitly for this webapp, resolve
+ tcpServerRequestPermissionPromise
and abort the
remaining steps.tcpServerRequestPermissionPromise
- and abort the remaining steps.tcpServerRequestPermissionPromise
+ and abort the remaining steps.tcpServerRequestPermissionPromise
- with DOMException "SecurityError"
. "SecurityError"
.
+
+
+
The UDPSocket interface defines attributes and methods for - UDP communication
- -- // +-The UDPSocket interface defines attributes and methods for + UDP communication
+ ++ // // This example shows a simple implementation of UPnP-SSDP M-SEARCH - // discovery using a multicast UDPSocket + // discovery using a multicast UDPSocket // - + var address = '239.255.255.250', port = '1900', serviceType = 'upnp:rootdevice', rn = '\r\n', search = ''; - + // Request permission to send multicast messages to the address and - // port reserved for SSDP - navigator.udpPermission.requestPermission({remoteAddress:"239.255.255.250", + // port reserved for SSDP + navigator.udpPermission.requestPermission({remoteAddress:"239.255.255.250", remotePort:1900}).then( () => { - // Permission was granted - + // Permission was granted + // Create a new UDP client socket var mySocket = new UDPSocket(); - + // Build an SSDP M-SEARCH multicast message search += 'M-SEARCH * HTTP/1.1' + rn; search += 'ST: ' + serviceType + rn; search += 'MAN: "ssdp:discover"' + rn; search += 'HOST: ' + address + ':' + port + rn; search += 'MX: 10'; - - + + // Receive and log SSDP M-SEARCH response messages - function receiveMSearchResponses() { - - // While data in buffer, read and log UDP message - while (mySocket.readable.state === "readable") { - var msg = mySocket.readable.read(); - console.log ('Remote address: ' + msg.remoteAddress + - ' Remote port: ' + msg.remotePort + - 'Message: ' + ab2str(msg.data)); - // ArrayBuffer to string conversion could also be done by piping - // through a transform stream. To be updated when the Streams API - // specification has been stabilized on this point. - } - - // Wait for SSDP M-SEARCH responses to arrive - mySocket.readable.ready.then(receiveMSearchResponses); + function receiveMSearchResponses() { + mySocket.readable.read().then(({ value, done }) => { + if (done) return; + + console.log ('Remote address: ' + value.remoteAddress + + 'Remote port: ' + value.remotePort + + 'Message: ' + ab2str(value.data)); + // ArrayBuffer to string conversion could also be done by piping + // through a transform stream. To be updated when the Streams API + // specification has been stabilized on this point. + }); } - + // Join SSDP multicast group mySocket.joinMulticast(address); - + // Send SSDP M-SEARCH multicast message mySocket.writeable.write( {data : str2ab(search), @@ -731,543 +727,541 @@- +Interface UDPSocket
}, e => console.error("Sending error: ", e); ); - - // Log result of UDP socket setup. + + // Log result of UDP socket setup. mySocket.opened.then( () => { console.log("UDP socket created sucessfully"); }, e =>console.error("UDP socket setup failed due to error: ", e); ); - - // Handle UDP socket closed, either as a result of the application - // calling mySocket.close() or an error causing the socket to be + + // Handle UDP socket closed, either as a result of the application + // calling mySocket.close() or an error causing the socket to be // closed. mySocket.closed.then( () => { console.log("Socket has been cleanly closed"); }, e => console.error("Socket closed due to error: ", e); - ); - + ); + }, e => console.error("Sending SSDP multicast messages was denied due - to error: ", e); - ); + to error: ", e); + ); -
options
argument's localAddress
member. If
- this member is not present but the remoteAddress
member is
- present, the user agent binds the socket to a local IPv4/6 address
- based on the routing table and possiby a preselect default local
- interface to use for the selected remoteAddress
. Else,
- i.e. neither the localAddress
or the
- remoteAddress
members are present in the constructor's
- options
argument, the localAddress
- attribute is set to null
.options
argument's localAddress
member. If
+ this member is not present but the remoteAddress
member is
+ present, the user agent binds the socket to a local IPv4/6 address
+ based on the routing table and possiby a preselect default local
+ interface to use for the selected remoteAddress
. Else,
+ i.e. neither the localAddress
or the
+ remoteAddress
members are present in the constructor's
+ options
argument, the localAddress
+ attribute is set to null
.options
argument in the constructor. If not set the
- user agent binds the socket to an ephemeral local port decided by
- the system and this attribute is null. true
allows the socket to be bound to a local address/port
- pair that already is in use. Can be set by the options
+ true
allows the socket to be bound to a local address/port
+ pair that already is in use. Can be set by the options
argument in the constructor. Default is true
.true
means that sent
- multicast data is looped back to the sender.
- Can be set by the options
argument in the constructor.
- Default is false
.true
means that sent
+ multicast data is looped back to the sender.
+ Can be set by the options
argument in the constructor.
+ Default is false
.openedPromise
that was created in the
- UDPSocket
constructor.
- openedPromise
that was created in the
+ UDPSocket
constructor.
+ close()
) or
+ close()
) or
through an error situation, e.g. network contact lost.
- Returns the closedPromise
that was created
- in the UDPSocket
constructor.
- closedPromise
that was created
+ in the UDPSocket
constructor.
+ Closes the UDP socket. Returns the closedPromise
that
- was created in the UDPSocket
constructor.
Closes the UDP socket. Returns the closedPromise
that
+ was created in the UDPSocket
constructor.
Joins a multicast group identified by the given address.
-Note that even if the socket is only sending to a multicast address, - it is a good practice to explicitely join the multicast group - (otherwise some routers may not relay packets).
- +Joins a multicast group identified by the given address.
+Note that even if the socket is only sending to a multicast address, + it is a good practice to explicitely join the multicast group + (otherwise some routers may not relay packets).
+Leaves a multicast group membership identified by the given address.
- +Leaves a multicast group membership identified by the given address.
+When the UDPSocket constructor is invoked, the user agent - MUST run the following steps: + + + + + +
When the UDPSocket constructor is invoked, the user agent + MUST run the following steps:
mySocket
").
- options
argument then throw DOMException "SecurityError"
and
- abort the remaining steps.
- options
argument's remoteAddress
- member is present and it is a valid host name or IPv4/6 address
- then set the mySocket.remoteAddress
attribute
- (default remote address) to the requested address. Else, if the
- remoteAddress
member is present but it is not a
- valid host name or IPv4/6 address then throw DOMException
+ abort the remaining steps.
+ options
argument's remoteAddress
+ member is present and it is a valid host name or IPv4/6 address
+ then set the mySocket.remoteAddress
attribute
+ (default remote address) to the requested address. Else, if the
+ remoteAddress
member is present but it is not a
+ valid host name or IPv4/6 address then throw DOMException
InvalidAccessError
and abort the remaining
steps.
- Otherwise, if the options
argument's remoteAddress
- member is absent then set the mySocket.remoteAddress
- attribute (default remote address) to null
.
- options
argument's remotePort
member
- is present and it is a valid port number then set the
- mySocket.remotePort
attribute (default remote port)
- to the requested port. Else, if the remotePort
member
- is present but it is not a valid port number then throw DOMException
+ Otherwise, if the options
argument's remoteAddress
+ member is absent then set the mySocket.remoteAddress
+ attribute (default remote address) to null
.
+ options
argument's remotePort
member
+ is present and it is a valid port number then set the
+ mySocket.remotePort
attribute (default remote port)
+ to the requested port. Else, if the remotePort
member
+ is present but it is not a valid port number then throw DOMException
InvalidAccessError
and abort the remaining steps.
- Otherwise, if the options
argument's remotePort
- member is absent then set the mySocket.remotePort
- attribute (default port number) to null
.
- options
argument's localAddress
- member is present and the options
argument's
- remoteAddress
member is present, execute the following
+ Otherwise, if the options
argument's remotePort
+ member is absent then set the mySocket.remotePort
+ attribute (default port number) to null
.
+ options
argument's localAddress
+ member is present and the options
argument's
+ remoteAddress
member is present, execute the following
step:
options
argument's localAddress
- member is a valid IPv4/6 address for a local interface that can
- be used to connect to the selected remoteAddress
- (according to the routing table) bind the socket to this local
- IPv4/6 address and set the mySocket.localAddress
- attribute to this addres. Else, if the localAddress
- member is present but it is not a valid local IPv4/6 address
- for a local interface that can be used to connect to the
- selected remoteAddress
, throw DOMException
- InvalidAccessError
and abort the remaining
- steps.
- options
argument's localAddress
- member is present and the options
argument's
- remoteAddress
member is absent, execute the following
+ options
argument's localAddress
+ member is a valid IPv4/6 address for a local interface that can
+ be used to connect to the selected remoteAddress
+ (according to the routing table) bind the socket to this local
+ IPv4/6 address and set the mySocket.localAddress
+ attribute to this addres. Else, if the localAddress
+ member is present but it is not a valid local IPv4/6 address
+ for a local interface that can be used to connect to the
+ selected remoteAddress
, throw DOMException
+ InvalidAccessError
and abort the remaining
+ steps.
+
+ Else, if the options
argument's localAddress
+ member is present and the options
argument's
+ remoteAddress
member is absent, execute the following
step:
options
argument's localAddress
- member is a valid IPv4/6 address for a local interface on the
- device bind the socket to this local IPv4/6 address and set the
- mySocket.localAddress
attribute to this addres.
- Else, if the localAddress
member is present but
- it is not a valid local IPv4/6 address for a local interface
- on the device, throw DOMException InvalidAccessError
- and abort the remaining steps. Note that binding the UDPSocket
- to a certain local interface means that the socket can only be
- used to send UDP datagrams to peers reachable through this
- local interface.
- options
argument's localAddress
- member is absent, and the options
argument's
- remoteAddress
member is present, execute the following
- steps:
+ options
argument's localAddress
+ member is a valid IPv4/6 address for a local interface on the
+ device bind the socket to this local IPv4/6 address and set the
+ mySocket.localAddress
attribute to this addres.
+ Else, if the localAddress
member is present but
+ it is not a valid local IPv4/6 address for a local interface
+ on the device, throw DOMException InvalidAccessError
+ and abort the remaining steps. Note that binding the UDPSocket
+ to a certain local interface means that the socket can only be
+ used to send UDP datagrams to peers reachable through this
+ local interface.
+
+ Else, if the options
argument's localAddress
+ member is absent, and the options
argument's
+ remoteAddress
member is present, execute the following
+ steps:
remoteAddress
. If no local interface can be used
- to send datagrams to the selected remoteAddress
,
- throw DOMException InvalidAccessError
and
+ can be used to send datagrams to the selected
+ remoteAddress
. If no local interface can be used
+ to send datagrams to the selected remoteAddress
,
+ throw DOMException InvalidAccessError
and
abort the remaining steps.
- remoteAddress
bind the socket to the IPv4/6 address
- of the "default" local interface to use for the selected
- remoteAddress
. The selection of a "default" local
+ remoteAddress
bind the socket to the IPv4/6 address
+ of the "default" local interface to use for the selected
+ remoteAddress
. The selection of a "default" local
interface is out of scope for this specification.
- mySocket.localAddress
attribute to the
- local address that the socket is bound to.
- options
argument's localAddress
- member is absent, and the options
argument's
- remoteAddress
member is absent, execute the following
- step:
+ mySocket.localAddress
attribute to the
+ local address that the socket is bound to.
+ options
argument's localAddress
+ member is absent, and the options
argument's
+ remoteAddress
member is absent, execute the following
+ step:
mySocket.localAddress
attribute to
+ mySocket.localAddress
attribute to
null
.
- options
argument's localPort
member
- is absent then bind the socket to an ephemeral local port decided
- by the system and set the mySocket.localPort
attribute
- to null.
- Otherwise, bind the socket to the requested local port and set the
- mySocket.localPort
attribute to the local port that
- the socket is bound to.
- mySocket.addressReuse
attribute to the value
- of the options
argument's addressReuse
- member if it is present or to true
if the options
- argument's addressReuse
member is not present.
- options
argument's loopback
member
- is present then set the mySocket.loopback
attribute
- to the value of this field. Else set this attribute to false
.
- mySocket.readyState
attribute to "opening".
- openedPromise
", and store
- it so it can later be returned by the opened
- property.
- closedPromise
", and store
- it so it can later be returned by the closed
- property and the close
method.
-
- mySocket.readable
attribute be a new
- ReadableStream object, [[!STREAMS]]. The user agent MUST implement
- the adaptation layer to [[!STREAMS]] for this new ReadableStream
- object through implementation of a number of functions that are
- given as input arguments to the constructor and called by the
- [[!STREAMS]] implementation. The semantics for these
+
+ options
argument's localPort
member
+ is absent then bind the socket to an ephemeral local port decided
+ by the system and set the mySocket.localPort
attribute
+ to null.
+ Otherwise, bind the socket to the requested local port and set the
+ mySocket.localPort
attribute to the local port that
+ the socket is bound to.
+ mySocket.addressReuse
attribute to the value
+ of the options
argument's addressReuse
+ member if it is present or to true
if the options
+ argument's addressReuse
member is not present.
+ options
argument's loopback
member
+ is present then set the mySocket.loopback
attribute
+ to the value of this field. Else set this attribute to false
.
+ mySocket.readyState
attribute to "opening".
+ openedPromise
", and store
+ it so it can later be returned by the opened
+ property.
+ closedPromise
", and store
+ it so it can later be returned by the closed
+ property and the close
method.
+
+ mySocket.readable
attribute be a new
+ ReadableStream object, [[!STREAMS]]. The user agent MUST implement
+ the adaptation layer to [[!STREAMS]] for this new ReadableStream
+ object through implementation of a number of functions that are
+ given as input arguments to the constructor and called by the
+ [[!STREAMS]] implementation. The semantics for these
functions are described below:
- start()
function is called
- immediately by the [[!STREAMS]] implementation.
+ start()
function is called
+ immediately by the [[!STREAMS]] implementation.
The start()
function MUST run the following steps:
openedPromise
.
+ openedPromise
.
mySocket.readyState
- attribute's value to "open".
+ mySocket.readyState
+ attribute's value to "open".
openedPromise
with
undefined
.
start()
function
- and MUST be called by the start()
function
+
+ The following internal methods of the ReadableStream are
+ arguments of the constructor's start()
function
+ and MUST be called by the start()
function
implementation according to the following steps:
- enqueue()
argument of start()
- is a function that pushes received data into the
+ enqueue()
argument of start()
+ is a function that pushes received data into the
internal buffer. data
member to a new read-only
- ArrayBuffer
object whose contents
- are the received UDP datagram [[!TYPED-ARRAYS]].
- remoteAddress
member of
- the UDPMessage object to the source
- address of the received UDP datagram.
- remotePort
member of the
- UDPMessage object to the source port
- of the received UDP datagram.
+ data
member to a new read-only
+ ArrayBuffer
object whose contents
+ are the received UDP datagram [[!TYPED-ARRAYS]].
+ remoteAddress
member of
+ the UDPMessage object to the source
+ address of the received UDP datagram.
+ remotePort
member of the
+ UDPMessage object to the source port
+ of the received UDP datagram.
enqueue()
to push the
- UDPMessage object into the internal
- [[!STREAMS]] receive buffer.
- Note that enqueue()
returns false if
+ UDPMessage object into the internal
+ [[!STREAMS]] receive buffer.
+ Note that enqueue()
returns false if
the high watermark of the buffer is reached.
However, as there is no flow control mechanism
in UDP the flow of datagrams can't be stopped.
- The enqueue()
return value should
+ The enqueue()
return value should
therefore be ignored. This means that datagrams
- will be lost if the internal receive buffer
+ will be lost if the internal receive buffer
has been filled to it's memory limit but
this is the nature of an unreliable protocol
- as UDP.
- error()
argument of start()
- is a function that handles readable stream errors and
- closes the readble stream.error()
argument of start()
+ is a function that handles readable stream errors and
+ closes the readble stream.mySocket.readyState
is "opening")
- has failed, e.g. because the local address/port pair is
+ has failed, e.g. because the local address/port pair is
already in use and mySocket.addressReuse
- is false
, the following steps MUST run:
- error()
with DOMException
+ is false
, the following steps MUST run:
+ error()
with DOMException
+ "NetworkError"
.
+ openedPromise
with DOMException
"NetworkError"
.
- openedPromise
with DOMException
- "NetworkError"
.
- closedPromise
with DOMException
- "NetworkError"
.
- mySocket.readyState
- attribute's value to "closed" and release any
- underlying resources associated with this socket.
- mySocket.readyState
- is "open"), e.g. network connection is lost, the
- following steps MUST run:
- error()
with DOMException
- "NetworkError"
.
- closedPromise
with
- DOMException "NetworkError"
.
- mySocket.readyState
- attribute's value to "closed" and release any
- underlying resources associated with this
- socket.
- ArrayBuffer
,
+ closedPromise
with DOMException
+ "NetworkError"
.
+ mySocket.readyState
+ attribute's value to "closed" and release any
+ underlying resources associated with this socket.
+ mySocket.readyState
+ is "open"), e.g. network connection is lost, the
+ following steps MUST run:
+ error()
with DOMException
+ "NetworkError"
.
+ closedPromise
with
+ DOMException "NetworkError"
.
+ mySocket.readyState
+ attribute's value to "closed" and release any
+ underlying resources associated with this
+ socket.
+ ArrayBuffer
,
[[!TYPED-ARRAYS]], the following steps MUST run:
error()
with TypeError
.
- closedPromise
with
- TypeError
.
- mySocket.readyState
- attribute's value to "closed" and release any
- underlying resources associated with this
- socket.
- error()
with TypeError
.
+ closedPromise
with
+ TypeError
.
+ mySocket.readyState
+ attribute's value to "closed" and release any
+ underlying resources associated with this
+ socket.
+
+
+ pull()
function MUST be omitted
as there is no flow control mechanism in UDP and the flow
- of datagrams cannot be stopped and started again.
- cancel()
function input
- argument is called by the [[!STREAMS]] implementation when
+ of datagrams cannot be stopped and started again.
+ cancel()
function input
+ argument is called by the [[!STREAMS]] implementation when
the ReadbleStream should be canceled. For UDP this means that
the UDP socket should be closed for reading and writing.
- The cancel()
function MUST run the following steps:
+ The cancel()
function MUST run the following steps:
mySocket.readyState
is "closed" then
- do nothing and abort the remaning steps.
- mySocket.readyState
is "opening"
+ mySocket.readyState
is "closed" then
+ do nothing and abort the remaning steps.
+ mySocket.readyState
is "opening"
then fail the UDP socket setup process, reject openedPromise
- with DOMException AbortError
and set the
+ with DOMException AbortError
and set the
mySocket.readyState
attribute to "closed".
- mySocket.readyState
is "open" the the
+ mySocket.readyState
is "open" the the
following steps MUST run:
- mySocket.writeable.close()
to
- assure that any buffered send data is sent.
- mySocket.readyState
- attribute's value to "closed".
- closedPromise
with
- undefined
and release any
- underlying resources associated with this
- socket.
- mySocket.writeable.close()
to
+ assure that any buffered send data is sent.
+ mySocket.readyState
+ attribute's value to "closed".
+ closedPromise
with
+ undefined
and release any
+ underlying resources associated with this
+ socket.
+
If the constructor's strategy
argument is
- omitted the
- Default strategy for Readable Streams
- applies. Currently this means that the ReadableStream
- object goes to "readable" state after 1 chunk has been
- enqueued to the internal ReadableStream object's input
- buffer. A webapp should use .ready to be notified
- when the state changes to "readable". To be further
- investigated which ReadableStreamStrategy that should
+ omitted the default backpressure behavior of readable streams
+ applies. Currently this means that the ReadableStream object
+ begins applying backpressure after 1 chunk has been enqueued
+ to the internal ReadableStream object's input buffer. To be
+ further investigated which readable stream strategy that should
be applied to UDP.
-
mySocket.writeable
attribute be a new
- WritableStream object, [[!STREAMS]]. The user agent MUST implement
- the adaptation layer to [[!STREAMS]] for this new WritableStream
- object through implementation of a number of functions that are
- given as input arguments to the constructor and called by the
- [[!STREAMS]] implementation. The semantics for these
+
+ mySocket.writeable
attribute be a new
+ WritableStream object, [[!STREAMS]]. The user agent MUST implement
+ the adaptation layer to [[!STREAMS]] for this new WritableStream
+ object through implementation of a number of functions that are
+ given as input arguments to the constructor and called by the
+ [[!STREAMS]] implementation. The semantics for these
functions are described below:
-
- start()
function MUST run the
following steps:
writableStartPromise
".
- mySocket.readable
- attribute constructor's start()
function )
+ mySocket.readable
+ attribute constructor's start()
function )
succeded resolve writableStartPromise
- with undefined
, else reject writableStartPromise
- with DOMException "NetworkError"
.
- write(chunk)
- function is called by the [[!STREAMS]] implementation to
- write UDP data. The write()
+ with undefined
, else reject writableStartPromise
+ with DOMException "NetworkError"
.
+
+ write(chunk)
+ function is called by the [[!STREAMS]] implementation to
+ write UDP data. The write()
function MUST run the following steps:
writePromise
"
- chunk
argument to a
- UDPMessage object (per [[!WEBIDL]] dictionary
+ chunk
argument to a
+ UDPMessage object (per [[!WEBIDL]] dictionary
conversion).
- options
argument's
- remoteAddress
member and the
- UDPMessage object's remoteAddress
- member is not present or null then throw DOMException
- InvalidAccessError
and abort these steps.
- options
argument's
- remotePort
member and the
- UDPMessage object's remotePort
- member is not present or null then throw DOMException
- InvalidAccessError
and abort these steps.
- remoteAddress
+ options
argument's
+ remoteAddress
member and the
+ UDPMessage object's remoteAddress
+ member is not present or null then throw DOMException
+ InvalidAccessError
and abort these steps.
+ options
argument's
+ remotePort
member and the
+ UDPMessage object's remotePort
+ member is not present or null then throw DOMException
+ InvalidAccessError
and abort these steps.
+ remoteAddress
and/or remotePort
member(s) are present but
the webapp does not have permission to send UDP
- packets to this address and port then throw DOMException
- SecurityError
and abort these steps.
- data
- member of the UDPMessage object. The destination
- address is the address defined by the
- UDPMesssage object's remoteAddress
+ packets to this address and port then throw DOMException
+ SecurityError
and abort these steps.
+ data
+ member of the UDPMessage object. The destination
+ address is the address defined by the
+ UDPMesssage object's remoteAddress
member if present, else the destination address
- is defined by the UDPSocket's constructor
- options
argument's
- remoteAddress
member. The destination
- port is the port defined by the
- UDPMesssage object's remotePort
+ is defined by the UDPSocket's constructor
+ options
argument's
+ remoteAddress
member. The destination
+ port is the port defined by the
+ UDPMesssage object's remotePort
member if present, else the destination port
- is defined by the UDPSocket's constructor
- options
argument's
- remotePort
member.
+ is defined by the UDPSocket's constructor
+ options
argument's
+ remotePort
member.
writePromise
with undefined
, else reject
writePromise
with DOMException
- "NetworkError"
.
- close()
and abort()
- functions MUST be omitted as it is not possible to just close
+ "NetworkError"
.
+
+
+ close()
and abort()
+ functions MUST be omitted as it is not possible to just close
the writable side of a UDP socket.
-
+
If the constructor's strategy
argument is
- omitted the
- Default strategy for Writable Streams
- applies. Currently this means that the WriteableStream
- object goes to "waiting" state after 1 chunk has been
+ omitted the
+ Default strategy for Writable Streams
+ applies. Currently this means that the WriteableStream
+ object goes to "waiting" state after 1 chunk has been
written to the internal WriteableStream object's output
buffer. This means that the webapp should use .ready
- to be notified of when the state changes to "writable",
+ to be notified of when the state changes to "writable",
i.e. the queued chunk has been written to the remote peer
- and more data chunks could be written. To be further
- investigated which WritableStreamStrategy that should
+ and more data chunks could be written. To be further
+ investigated which WritableStreamStrategy that should
be applied to UDP.
-
UDPSocket
object ("mySocket
")
to the webapp.
-
-
-
- The close
method when invoked MUST run the
+
+
The close
method when invoked MUST run the
following steps:
closedPromise
.
+ closedPromise
.
The TCPSocket interface defines attributes and methods for TCP - communication
- +The TCPSocket interface defines attributes and methods for TCP + communication
+- // - // This example shows a simple TCP echo client. - // The client will send "Hello World" to the server on port 6789 and log + // + // This example shows a simple TCP echo client. + // The client will send "Hello World" to the server on port 6789 and log // what has been received from the server. - // - + // + // Request permission to connect to server at address 127.0.0.1 on port // 6789 - + navigator.tcpPermission.requestPermission({remoteAddress:"127.0.0.1", remotePort:6789}).then( () => { - // Permission was granted - // Create a new TCP client socket and connect to remote host + // Permission was granted + // Create a new TCP client socket and connect to remote host var mySocket = new TCPSocket("127.0.0.1", 6789); - + // Send data to server mySocket.writeable.write("Hello World").then( () => { - + // Data sent sucessfully, wait for response console.log("Data has been sent to server"); - mySocket.readable.ready.then( - () => { - - // Data in buffer, read it - console.log("Data received from server:" + mySocket.readable.read()); - + mySocket.readable.read().then( + ({ value, done }) => { + if (!done) { + // Response received, log it: + console.log("Data received from server:" + value); + } + // Close the TCP connection mySocket.close(); } @@ -1275,20 +1269,20 @@- -Interface TCPSocket
}, e => console.error("Sending error: ", e); ); - + // Signal that we won't be writing any more and can close the write half of the connection. mySocket.halfClose(); - - // Log result of TCP connection attempt. + + // Log result of TCP connection attempt. mySocket.opened.then( () => { console.log("TCP connection established sucessfully"); }, e =>console.error("TCP connection setup failed due to error: ", e); ); - - // Handle TCP connection closed, either as a result of the webapp - // calling mySocket.close() or the other side closed the TCP + + // Handle TCP connection closed, either as a result of the webapp + // calling mySocket.close() or the other side closed the TCP // connection or an error causing the TCP connection to be closed. mySocket.closed.then( () => { @@ -1297,436 +1291,433 @@Interface TCPSocket
e => console.error("TCP socket closed due to error: ", e); ); }, - e => console.error("Connection to 127.0.0.1 on port 6789 was denied - due to error: ", e); - ); -
options
- argument in the constructor. If not set the user agent
- binds the socket to an IPv4/6 address based on the routing table and
- possibly a preselect default local interface to use for the selected
- remoteAddress
. remoteAddress
. options
argument in the constructor. If not set the
- user agent binds the socket to an ephemeral local port decided by
- the system. true
allows the socket to be bound to a local address/port
- pair that already is in use. Can be set by the options
- argument in the constructor. Default is true
.true
allows the socket to be bound to a local address/port
+ pair that already is in use. Can be set by the options
+ argument in the constructor. Default is true
.true
if the Nagle algorithm for send coalescing,
- [[!NAGLE]], is disabled. Can be set by the
- options
argument in the constructor. Default is
- true
.true
if the Nagle algorithm for send coalescing,
+ [[!NAGLE]], is disabled. Can be set by the
+ options
argument in the constructor. Default is
+ true
.openedPromise
that was created
- in the TCPSocket
constructor.
- openedPromise
that was created
+ in the TCPSocket
constructor.
+ close()
) or through an error situation.
- Returns the closedPromise
that was created
- in the TCPSocket
constructor.
- closedPromise
that was created
+ in the TCPSocket
constructor.
+ Closes the TCP socket. Returns the closedPromise
that
- was created in the TCPSocket
constructor.
Closes the TCP socket. Returns the closedPromise
that
+ was created in the TCPSocket
constructor.
Half closes the TCP socket.
-When the TCPSocket constructor is invoked, the user agent MUST - run the following steps: +
Half closes the TCP socket.
+When the TCPSocket constructor is invoked, the user agent MUST + run the following steps:
mySocket
").
- remoteAddress
/remotePort
- as stated by the input arguments, then throw DOMException
+ as stated by the input arguments, then throw DOMException
"SecurityError"
and abort the remaining steps.
remoteAddress
argument is not a valid host name
- or IPv4/6 address and/or the remotePort
argument is
- not a valid port number then throw DOMException "InvalidAccessError"
- and abort the remaining steps, else set the mySocket.remoteAddress
+ or IPv4/6 address and/or the remotePort
argument is
+ not a valid port number then throw DOMException "InvalidAccessError"
+ and abort the remaining steps, else set the mySocket.remoteAddress
and mySocket.remotePort
attributes to the requested values.
- options
argument's localAddress
+ options
argument's localAddress
member is present and it is a valid IPv4/6 address for a local
- interface that can be used to connect to the selected
- remoteAddress
(according to the routing table) bind the
- socket to this local IPv4/6 address and set the mySocket.localAddress
- attribute to this addres. Else, if the localAddress
- member is present but it is not a valid local IPv4/6 address for a
- local interface that can be used to connect to the selected
- remoteAddress
then throw DOMException
+ interface that can be used to connect to the selected
+ remoteAddress
(according to the routing table) bind the
+ socket to this local IPv4/6 address and set the mySocket.localAddress
+ attribute to this addres. Else, if the localAddress
+ member is present but it is not a valid local IPv4/6 address for a
+ local interface that can be used to connect to the selected
+ remoteAddress
then throw DOMException
"InvalidAccessError"
and abort the remaining steps.options
argument's localAddress
- member is absent, execute the following steps:
+ Otherwise, if the options
argument's localAddress
+ member is absent, execute the following steps:
remoteAddress
.
- If no local interface can be used to connect to the selected
- remoteAddress
then throw DOMException
- "InvalidAccessError"
and abort the remaining
+ can be used to connect to the selected remoteAddress
.
+ If no local interface can be used to connect to the selected
+ remoteAddress
then throw DOMException
+ "InvalidAccessError"
and abort the remaining
steps.
- remoteAddress
- bind the socket to the IPv4/6 address of the "default" local
- interface to use for the selected remoteAddress
.
- The selection of a "default" local interface is out of scope
+ bind the socket to the IPv4/6 address of the "default" local
+ interface to use for the selected remoteAddress
.
+ The selection of a "default" local interface is out of scope
for this specification.
- mySocket.localAddress
attribute to the
- local address that the socket is bound to.
- options
argument's localPort
member
- is absent then bind the socket to an ephemeral local port decided
- by the system and set the mySocket.localPort
attribute
- to this port.
- Otherwise, bind the socket to the requested local port and set the
- mySocket.localPort
attribute to the local port that
- the socket is bound to.
- mySocket.addressReuse
attribute to the value
- of the options
argument's addressReuse
- member if it is present or to true
if the options
+ mySocket.localAddress
attribute to the
+ local address that the socket is bound to.
+ options
argument's localPort
member
+ is absent then bind the socket to an ephemeral local port decided
+ by the system and set the mySocket.localPort
attribute
+ to this port.
+ Otherwise, bind the socket to the requested local port and set the
+ mySocket.localPort
attribute to the local port that
+ the socket is bound to.
+ mySocket.addressReuse
attribute to the value
+ of the options
argument's addressReuse
+ member if it is present or to true
if the options
argument's addressReuse
member is not present.
- mySocket.noDelay
attribute to the value of
- the options
argument's noDelay
member
- if it is present or to true
if the options
- argument's noDelay
member is not present.
- mySocket.readyState
attribute to "opening".
- openedPromise
", and store
- it so it can later be returned by the opened
- property.
- closedPromise
", and store
- it so it can later be returned by the closed
- property and the close
method.
-
- mySocket.readable
attribute be a new
- ReadableStream object, [[!STREAMS]]. The user agent MUST implement
- the adaptation layer to [[!STREAMS]] for this new ReadableStream
- object through implementation of a number of functions that are
- given as input arguments to the constructor and called by the
- [[!STREAMS]] implementation. The semantics for these
+ mySocket.noDelay
attribute to the value of
+ the options
argument's noDelay
member
+ if it is present or to true
if the options
+ argument's noDelay
member is not present.
+ mySocket.readyState
attribute to "opening".
+ openedPromise
", and store
+ it so it can later be returned by the opened
+ property.
+ closedPromise
", and store
+ it so it can later be returned by the closed
+ property and the close
method.
+
+ mySocket.readable
attribute be a new
+ ReadableStream object, [[!STREAMS]]. The user agent MUST implement
+ the adaptation layer to [[!STREAMS]] for this new ReadableStream
+ object through implementation of a number of functions that are
+ given as input arguments to the constructor and called by the
+ [[!STREAMS]] implementation. The semantics for these
functions are described below:
- start()
function is called
- immediately by the [[!STREAMS]] implementation.
+ start()
function is called
+ immediately by the [[!STREAMS]] implementation.
The start()
function MUST run the following steps:
openedPromise
.
- mySocket.readyState
attribute's value to
- "open".
+ mySocket.readyState
attribute's value to
+ "open".
openedPromise
with undefined
.
start()
function and MUST be called by the
+
+ The following functions are arguments of the constructor's
+ start()
function and MUST be called by the
start()
function implementation according to the
following steps:
- enqueue()
argument of start()
- is a function that pushes received data into the
+ enqueue()
argument of start()
+ is a function that pushes received data into the
internal buffer. ArrayBuffer
+ ArrayBuffer
object whose contents are the received TCP data.
enqueue()
to push the
- ArrayBuffer
into the internal
- [[!STREAMS]] receive buffer.
- enqueue()
returns false and the TCP
- flow control MUST be used to stop the data
- transmission from the remote peer.
- close()
argument of start()
- is a function that closes the readable stream.ArrayBuffer
into the internal
+ [[!STREAMS]] receive buffer.
+ enqueue()
returns false and the TCP
+ flow control MUST be used to stop the data
+ transmission from the remote peer.
+ close()
argument of start()
+ is a function that closes the readable stream.close()
)
- through a successful TCP connection closing handshake
- the following steps MUST run:
- close()
.
- mySocket.readyState
attribute's
- value to "closed" and release any
- underlying resources associated with this socket.
- closedPromise
with
- undefined
.
- error()
argument of start()
- is a function that handles readable stream errors and
- closes the readble stream.mySocket.readyState
is "opening") has
- failed the following steps MUST run:
- error()
with DOMException
+ cleanly (initiated either by the server, or by
+ the client webapp calling close()
)
+ through a successful TCP connection closing handshake
+ the following steps MUST run:
+ close()
.
+ mySocket.readyState
attribute's
+ value to "closed" and release any
+ underlying resources associated with this socket.
+ closedPromise
with
+ undefined
.
+ error()
argument of start()
+ is a function that handles readable stream errors and
+ closes the readble stream.mySocket.readyState
is "opening") has
+ failed the following steps MUST run:
+ error()
with DOMException
+ "NetworkError"
.
+ openedPromise
with DOMException
+ "NetworkError"
.
+ closedPromise
with DOMException
+ "NetworkError"
.
+ mySocket.readyState
attribute's value
+ to "closed" and release any underlying resources
+ associated with this socket.
+ mySocket.readyState
is "open") has been lost
+ the following steps MUST run:
+ error()
with DOMException
+ "NetworkError"
.
+ closedPromise
with DOMException
"NetworkError"
.
- openedPromise
with DOMException
- "NetworkError"
.
- closedPromise
with DOMException
- "NetworkError"
.
- mySocket.readyState
attribute's value
- to "closed" and release any underlying resources
- associated with this socket.
- mySocket.readyState
is "open") has been lost
- the following steps MUST run:
- error()
with DOMException
- "NetworkError"
.
- closedPromise
with DOMException
- "NetworkError"
.
- mySocket.readyState
- attribute's value to "closed" and release any
- underlying resources associated with this
- socket.
- mySocket.readyState
+ attribute's value to "closed" and release any
+ underlying resources associated with this
+ socket.
+ mySocket.readyState
is "closing")
- has failed the following steps MUST run:
- error()
with DOMException
- "NetworkError"
.
- closedPromise
with DOMException
- "NetworkError"
.
- mySocket.readyState
- attribute's value to "closed" and release any
- underlying resources associated with this socket.
- ArrayBuffer
,
+ has failed the following steps MUST run:
+ error()
with DOMException
+ "NetworkError"
.
+ closedPromise
with DOMException
+ "NetworkError"
.
+ mySocket.readyState
+ attribute's value to "closed" and release any
+ underlying resources associated with this socket.
+ ArrayBuffer
,
[[!TYPED-ARRAYS]], the following steps MUST run:
error()
with TypeError
.
- closedPromise
with
- TypeError
.
- mySocket.readyState
- attribute's value to "closed" and release any
- underlying resources associated with this socket.
- pull()
function is called
- by the [[!STREAMS]] implementation if the internal buffer
- has been emptied, but the stream's consumer still wants more
- data.
+ error()
with TypeError
.
+ closedPromise
with
+ TypeError
.
+ mySocket.readyState
+ attribute's value to "closed" and release any
+ underlying resources associated with this socket.
+
+ pull()
function is called
+ by the [[!STREAMS]] implementation if the internal buffer
+ has been emptied, but the stream's consumer still wants more
+ data.
The pull()
function MUST run the following steps:
cancel()
function input
- argument is called by the [[!STREAMS]] implementation when
+ cancel()
function input
+ argument is called by the [[!STREAMS]] implementation when
the ReadbleStream should be canceled. For TCP this means that
the TCP connection should be terminated.
- The cancel()
function MUST run the following steps:
+ The cancel()
function MUST run the following steps:
mySocket.readyState
is "closing" or "closed" then
- do nothing and abort the remaning steps.
- mySocket.readyState
is "opening" then fail the
+ mySocket.readyState
is "closing" or "closed" then
+ do nothing and abort the remaning steps.
+ mySocket.readyState
is "opening" then fail the
connection attempt, reject openedPromise
and
- closedPromise
with DOMException
+ closedPromise
with DOMException
AbortError
and set the mySocket.readyState
- attribute to "closing".
- mySocket.readyState
is "open" then the
+ attribute to "closing".
+ mySocket.readyState
is "open" then the
following steps MUST run:
- mySocket.writeable.close()
to
- assure that any buffered send data is sent
- before closing the socket.
- mySocket.readyState
- attribute's value to "closing".
- mySocket.writeable.close()
to
+ assure that any buffered send data is sent
+ before closing the socket.
+ mySocket.readyState
+ attribute's value to "closing".
+
If the constructor's strategy
argument is
- omitted the
- Default strategy for Readable Streams
- applies. Currently this means that the ReadableStream
- object goes to "readable" state after 1 chunk has been
- enqueued to the internal ReadableStream object's input
- buffer. A webapp should use .ready to be notified
- when the state changes to "readable". To be further
- investigated which ReadableStreamStrategy that should
+ omitted the default backpressure behavior of readable streams
+ applies. Currently this means that the ReadableStream object
+ begins applying backpressure after 1 chunk has been enqueued
+ to the internal ReadableStream object's input buffer. To be
+ further investigated which readable stream strategy that should
be applied to TCP.
-
mySocket.writeable
attribute be a new
- WritableStream object, [[!STREAMS]]. The user agent MUST implement
- the adaptation layer to [[!STREAMS]] for this new WritableStream
- object through implementation of a number of functions that are
- given as input arguments to the constructor and called by the
- [[!STREAMS]] implementation. The semantics for these
+
+ mySocket.writeable
attribute be a new
+ WritableStream object, [[!STREAMS]]. The user agent MUST implement
+ the adaptation layer to [[!STREAMS]] for this new WritableStream
+ object through implementation of a number of functions that are
+ given as input arguments to the constructor and called by the
+ [[!STREAMS]] implementation. The semantics for these
functions are described below:
-
- start()
function MUST run the
following steps:
writableStartPromise
".
mySocket.readable
attribute
+ for the mySocket.readable
attribute
constructor's start()
function ) succeded
resolve writableStartPromise
with undefined
, else reject
writableStartPromise
with DOMException
- "NetworkError"
.
- write(chunk)
function is
+ "NetworkError"
.
+
+ write(chunk)
function is
called by the [[!STREAMS]] implementation to write data to
the remote peer on the TCP connection.
The write()
function MUST run the following steps:
writePromise
"
chunk
- parameter to the address and port of the recipient as
- stated by the TCPSocket object constructor's
- remoteAddress
and remotePort
- fields. The data in the chunk
parameter
- can be of any type.
+ parameter to the address and port of the recipient as
+ stated by the TCPSocket object constructor's
+ remoteAddress
and remotePort
+ fields. The data in the chunk
parameter
+ can be of any type.
writePromise
with undefined
, else reject
writePromise
with DOMException
- "NetworkError"
.
- close()
function is called
- by the [[!STREAMS]] implementation to close the writable
- side of the connection, that is a TCP "half close" is
- performed. The close()
function MUST run the
+ "NetworkError"
.
+
+ close()
function is called
+ by the [[!STREAMS]] implementation to close the writable
+ side of the connection, that is a TCP "half close" is
+ performed. The close()
function MUST run the
following steps:
mySocket.readyState
is "closing" or "closed" then
+ mySocket.readyState
is "closing" or "closed" then
do nothing.
- mySocket.readyState
is "opening" then complete
- the connection attempt. If succesful send FIN and set the
+ mySocket.readyState
is "opening" then complete
+ the connection attempt. If succesful send FIN and set the
mySocket.readyState
attribute to "halfclosed".
- mySocket.readyState
is "open" then send FIN and
- set the mySocket.readyState
attribute to "halfclosed".
+ mySocket.readyState
is "open" then send FIN and
+ set the mySocket.readyState
attribute to "halfclosed".
close()
after all queued-up writes successfully completed.
- abort()
function is called
- by the [[!STREAMS]] implementation to abort the writable
+ abort()
function is called
+ by the [[!STREAMS]] implementation to abort the writable
side of the connection. This function MUST run the same steps
- as close()
but note that the Streams
- implementation will throw away any pending queued up chunks.
-
+ as close()
but note that the Streams
+ implementation will throw away any pending queued up chunks.
+
If the constructor's strategy
argument is
- omitted the
- Default strategy for Writable Streams
- applies. Currently this means that the WriteableStream
- object goes to "waiting" state after 1 chunk has been
+ omitted the
+ Default strategy for Writable Streams
+ applies. Currently this means that the WriteableStream
+ object goes to "waiting" state after 1 chunk has been
written to the internal WriteableStream object's output
- buffer. This means that the webapp should use .ready
- to be notified of when the state changes to "writable",
+ buffer. This means that the webapp should use .ready
+ to be notified of when the state changes to "writable",
i.e. the queued chunk has been written to the remote peer
- and more data chunks could be written. To be further
- investigated which WritableStreamStrategy that should
+ and more data chunks could be written. To be further
+ investigated which WritableStreamStrategy that should
be applied to TCP.
-
mySocket
")
+
+
+ mySocket
")
to the webapp.
-
-
- The close()
method when invoked MUST run the
+
The close()
method when invoked MUST run the
following steps:
mysocket.readable.cancel(reason)
. (Reason codes TBD.)
+ mysocket.readable.cancel(reason)
. (Reason codes TBD.)
closedPromise
.
The halfClose()
method when invoked MUST run the
+
The halfClose()
method when invoked MUST run the
following steps:
mysocket.writeable.close()
.
+ mysocket.writeable.close()
.
The TCPServerSocket interface supports TCP server sockets that - listens to connection attempts from TCP clients
- +The TCPServerSocket interface supports TCP server sockets that + listens to connection attempts from TCP clients
+- // - // This example shows a simple TCP echo server. - // The server will listen on port 6789 and respond back with whatever + // + // This example shows a simple TCP echo server. + // The server will listen on port 6789 and respond back with whatever // has been sent to the server. - // - - // Request permission to listen on port 6789 + // + + // Request permission to listen on port 6789 navigator.tcpServerPermission.requestPermission({"localPort":6789}).then( () => { - // Permission was granted - + // Permission was granted + // Create a new server socket that listens on port 6789 var myServerSocket = new TCPServerSocket({"localPort": 6789}); @@ -1736,54 +1727,53 @@- - -Interface TCPServerSocket
myServerSocket.listen().then( connectedSocket => { // A connection has been accepted - - console.log ("Connection accepted from address: " + - connectedSocket.remoteAddress + " port: " + - connectedSocket.remotePort); + + console.log ("Connection accepted from address: " + + connectedSocket.remoteAddress + " port: " + + connectedSocket.remotePort); // Wait for data - waitForData (); - function waitForData () { - connectedSocket.readable.ready.then( - () => { - // Data in buffer, read it - var receivedData = connectedSocket.readable.read(); - console.log ("Received: " + receivedData); - - // Send data back - connected.writeable.write(receivedData).then( - () => { - console.log ("Sending data succeeded"); - }, - e => console.error("Failed to send: ", e); - }, - // Continue to wait for data - waitForData (); - } + waitForData(); + function waitForData () { + connectedSocket.readable.read().then( + ({ value, done }) => { + if (done) return; + + // Data in buffer, read it + console.log("Received: " + value); + + // Send data back + connected.writeable.write(value).then( + () => console.log("Sending data succeeded"), + e => console.error("Failed to send: ", e); + }); + // Continue to wait for data + waitForData (); + } ); - + } - + // Continue to listen for new connections - listenForConnections(); + listenForConnections(); }, e => { console.error("A client connection attempt failed: ", e); - + // Continue to listen for new connections - listenForConnections(); - } - + listenForConnections(); + } + ); } - - // Log result of TCP server socket creation attempt. + + // Log result of TCP server socket creation attempt. myServerSocket.opened.then( () => { console.log("TCP server socket created sucessfully"); }, e =>console.error("TCP server socket creation failed due to error: ", e); ); - + // Handle TCP server closed, either as a result of the webapp // calling myServerSocket.close() or due to an error. myServerSocket.closed.then( @@ -1792,543 +1782,543 @@Interface TCPServerSocket
}, e => console.error("TCP server socket closed due to error: ", e); ); - + }, - e => console.error("TCP Server Socket on local port 6789 was denied - due to error: ", e); - ); + e => console.error("TCP Server Socket on local port 6789 was denied + due to error: ", e); + ); + +
options
argument in the constructor. If not set the
- the server will accept connections directed to any IPv4 address
- and this atribute is set to null
.
- options
argument in the constructor. If not set the
+ the server will accept connections directed to any IPv4 address
+ and this atribute is set to null
.
+ options
argument in the constructor. If not
- set the user agent binds the socket to an ephemeral local port
- decided by the system and sets this atribute to null
.
- options
argument in the constructor. If not
+ set the user agent binds the socket to an ephemeral local port
+ decided by the system and sets this atribute to null
.
+ true
allows the socket to be bound to a local
- address/port pair that already is in use. Can be set by the
- options
argument in the constructor. Default is
- true
.true
allows the socket to be bound to a local
+ address/port pair that already is in use. Can be set by the
+ options
argument in the constructor. Default is
+ true
.openedPromise
that was created in the
- TCPServerSocket
constructor.
- openedPromise
that was created in the
+ TCPServerSocket
constructor.
+ close()
) or through
- an error situation. Returns the closedPromise
that
- was created in the TCPSocket
constructor.
- close()
) or through
+ an error situation. Returns the closedPromise
that
+ was created in the TCPSocket
constructor.
+ Listens for incoming connection attempts on the specified port and
- address. Returns the connectionPromise
, which is for
- a succeful connection resolved with the TCPSocket
+
Listens for incoming connection attempts on the specified port and
+ address. Returns the connectionPromise
, which is for
+ a succeful connection resolved with the TCPSocket
object for the accepted TCP connection and rejected with
- DOMException "NetworkError"
if there is an error on
- an incoming connection attempt.
"NetworkError"
if there is an error on
+ an incoming connection attempt.
+ Closes the TCP server socket. If listen()
has been
- called the listening for incoming connections is stopped but existing
- TCP connections are kept open. Returns the
- closedPromise
that was created in the
- TCPServerSocket
constructor.
When the TCPServerSocket constructor is invoked, the user agent - MUST run the following steps: +
Closes the TCP server socket. If listen()
has been
+ called the listening for incoming connections is stopped but existing
+ TCP connections are kept open. Returns the
+ closedPromise
that was created in the
+ TCPServerSocket
constructor.
When the TCPServerSocket constructor is invoked, the user agent + MUST run the following steps:
myServerSocket
").
- options
argument then throw DOMException "SecurityError"
and
- abort the remaining steps.
- options
argument's localAddress
- member is absent the server will accept connections directed to
+ abort the remaining steps.
+ options
argument's localAddress
+ member is absent the server will accept connections directed to
any IPv4 address and the localAddress
attribute is
- set to null
.
+ set to null
.
Otherwise, if the requested local address is a valid IPv4/6 address
for a local interface on the device bind the server socket to this
- local IPv4/6 address and set the localAddress
- attribute to this address. Else, if the localAddress
+ local IPv4/6 address and set the localAddress
+ attribute to this address. Else, if the localAddress
member is present but it is not a valid local IPv4/6 address for a
- local interface on the device, throw DOMException InvalidAccessError
- and abort the remaining steps.
+ local interface on the device, throw DOMException InvalidAccessError
+ and abort the remaining steps.
options
argument's localPort
member
- is absent then bind the socket to an ephemeral local port decided
- by the system and set the localPort
attribute to
- null
.
- Otherwise, bind the socket to the requested local port and
- set the localPort
attribute to the local port that the
- socket is bound to.
+ is absent then bind the socket to an ephemeral local port decided
+ by the system and set the localPort
attribute to
+ null
.
+ Otherwise, bind the socket to the requested local port and
+ set the localPort
attribute to the local port that the
+ socket is bound to.
addressReuse
attribute to the value of the
- options
argument's addressReuse
member
- if it is present or to true
if the options
- argument's addressReuse
member is not present.
- myServerSocket.readyState
attribute to "opening".
- openedPromise
", and store
- it so it can later be returned by the opened
- property.
- closedPromise
", and store
- it so it can later be returned by the closed
- property and the close
method.
- options
argument's addressReuse
member
+ if it is present or to true
if the options
+ argument's addressReuse
member is not present.
+ myServerSocket.readyState
attribute to "opening".
+ openedPromise
", and store
+ it so it can later be returned by the opened
+ property.
+ closedPromise
", and store
+ it so it can later be returned by the closed
+ property and the close
method.
+ The close
method when invoked MUST run the
+
The close
method when invoked MUST run the
following steps:
myServerSocket.readyState
attribute to "closed".
- closedPromise
with
- undefined
.
+ closedPromise
with
+ undefined
.
The listen
method when invoked MUST run the
+
The listen
method when invoked MUST run the
following steps:
myServerSocket.readyState
attribute is"closed" then
- throw DOMException "InvalidStateError"
and abort the
+ throw DOMException "InvalidStateError"
and abort the
remaining steps.
connectionPromise
".
- connectionPromise
.
+ connectionPromise
.
When a new TCP server socket has successfully been created the +
+ +When a new TCP server socket has successfully been created the user agent MUST run the following steps: - +
myServerSocket.readyState
attribute's value to "open".
- openedPromise
with undefined
.
+ myServerSocket.readyState
attribute's value to "open".
+ openedPromise
with undefined
.
When the attempt to create a new TCP server socket
- (myServerSocket.readyState
is "opening") has failed the
+
When the attempt to create a new TCP server socket
+ (myServerSocket.readyState
is "opening") has failed the
user agent MUST run the following steps:
-
+
myServerSocket.readyState
attribute's value to
- "closed".
- openedPromise
with DOMException
- "NetworkError"
.
- closedPromise
with DOMException
- "NetworkError"
.
- When there is an error on an established TCP server socket +
myServerSocket.readyState
attribute's value to
+ "closed".
+ openedPromise
with DOMException
+ "NetworkError"
.
+ closedPromise
with DOMException
+ "NetworkError"
.
+
+
+
+ When there is an error on an established TCP server socket
(myServerSocket.readyState
is "open"), e.g. loss of network
contact, the user agent MUST run the following steps:
-
+
myServerSocket.readyState
attribute's value to
- "closed".
- closedPromise
with DOMException
- "NetworkError"
.
- Upon a new successful connection to the TCP server socket the +
myServerSocket.readyState
attribute's value to
+ "closed".
+ closedPromise
with DOMException
+ "NetworkError"
.
+
+
+
+ Upon a new successful connection to the TCP server socket the user agent MUST run the following steps: - +
remoteAddress
attribute of socket
- to the IPv4/6 address of the peer.
- remotePort
attribute of socket
- to the source port of the of the peer.
- localAddress
attribute of socket
- to the used local IPv4/6 address.
- localPort
attribute of socket to
- the used local source port.
- readyState
attribute of socket
- to "open".
- bufferedAmount
attribute of socket
- to 0.
+ remoteAddress
attribute of socket
+ to the IPv4/6 address of the peer.
+ remotePort
attribute of socket
+ to the source port of the of the peer.
+ localAddress
attribute of socket
+ to the used local IPv4/6 address.
+ localPort
attribute of socket to
+ the used local source port.
+ readyState
attribute of socket
+ to "open".
+ bufferedAmount
attribute of socket
+ to 0.
connectionPromise
with socket as
- argument.
+ argument.
Upon a new connection attempt to the TCP server socket that can not be - served, e.g. due to max number of open connections, the user agent +
+ +Upon a new connection attempt to the TCP server socket that can not be + served, e.g. due to max number of open connections, the user agent MUST run the following steps: - +
connectionPromise
with DOMException
- "NetworkError"
.
+ connectionPromise
with DOMException
+ "NetworkError"
.
The UDPMessage dictionary represents UDP data including - address and port of the remote peer. The field data is mandatory - but remoteAddress and remotePort are optional.
+ address and port of the remote peer. The field data is mandatory + but remoteAddress and remotePort are optional.- States the options for the UDPSocket. An instance of this dictionary can - optionally be used in the constructor of the UDPSocket object, where + States the options for the UDPSocket. An instance of this dictionary can + optionally be used in the constructor of the UDPSocket object, where all fields are optional. -
+remoteAddress
if this member is present. Else the
- UDPSocket is unbound to a local interface. remoteAddress
if this member is present. Else the
+ UDPSocket is unbound to a local interface. true
allows the socket to be bound to a local address/port pair that
+ true
allows the socket to be bound to a local address/port pair that
already is in use. Default is true
.true
means that sent
- multicast data is looped back to the sender.
- Default is false
.true
means that sent
+ multicast data is looped back to the sender.
+ Default is false
.- States the options for the TCPSocket. An instance of this dictionary can - optionally be used in the constructor of the TCPSocket object, - where all fields are optional. -
+ States the options for the TCPSocket. An instance of this dictionary can + optionally be used in the constructor of the TCPSocket object, + where all fields are optional. +remoteAddress
. remoteAddress
. true
allows the socket to be bound to a local
+ true
allows the socket to be bound to a local
address/port pair that already is in use. Default is true
.
- true
if the Nagle algorithm for send coalescing,
- [[!NAGLE]], is disabled. Default is
- true
.true
if the Nagle algorithm for send coalescing,
+ [[!NAGLE]], is disabled. Default is
+ true
.true
if socket uses SSL or TLS. Default is
+ true
if socket uses SSL or TLS. Default is
false
.- Use of secure transport needs more investigation -
-- States the options for the TCPServerSocket. An instance of this dictionary + States the options for the TCPServerSocket. An instance of this dictionary can optionally be used in the constructor of the TCPServerSocket object, where all fields are optional. -
+true
allows the socket to be bound to a local
- address/port pair that already is in use. Default is
- true
.true
allows the socket to be bound to a local
+ address/port pair that already is in use. Default is
+ true
.true
if socket uses SSL or TLS. Default is
- false
.true
if socket uses SSL or TLS. Default is
+ false
.- Use of secure transport needs more investigation -
+ Use of secure transport needs more investigation + + +
- States the options for the webapp to get status of permission
- for creating a UDPSocket object or to request permission to
- create a UDPSocket object. An instance of this dictionary can
+ States the options for the webapp to get status of permission
+ for creating a UDPSocket object or to request permission to
+ create a UDPSocket object. An instance of this dictionary can
optionally be used as argument to the UDPPermission hasPermission
- and requestPermission
methods. All fields are optional.
-
requestPermission
methods. All fields are optional.
+
- States the options for the webapp to get status of permission
- for creating a TCPSocket object or to request permission to
- create a TCPSocket object. An instance of this dictionary can
+ States the options for the webapp to get status of permission
+ for creating a TCPSocket object or to request permission to
+ create a TCPSocket object. An instance of this dictionary can
optionally be used as argument to the TCPPermission hasPermission
- and requestPermission
methods. All fields are optional.
-
requestPermission
methods. All fields are optional.
+
- States the options for the webapp to get status of permission
- for creating a TCPServerSocket object or to request permission to
- create a TCPServerSocket object. An instance of this dictionary can
- optionally be used as argument to the TCPServerPermission
+ States the options for the webapp to get status of permission
+ for creating a TCPServerSocket object or to request permission to
+ create a TCPServerSocket object. An instance of this dictionary can
+ optionally be used as argument to the TCPServerPermission
hasPermission
and requestPermission
methods.
- All fields are optional.
-
requestPermission
.requestPermission
.- Many thanks to Domenic Denicola, Marcos Caceres, Jonas Sicking, Ke-Fong Lin and - Alexandre Morgaut for reviewing the specification and providing very + Many thanks to Domenic Denicola, Marcos Caceres, Jonas Sicking, Ke-Fong Lin and + Alexandre Morgaut for reviewing the specification and providing very valuable feedback. Also thanks to Sony colleagues Anders Edenbrandt, - Anders Isberg and Björn Isaksson for sharing their experience on + Anders Isberg and Björn Isaksson for sharing their experience on socket APIs and providing support.