diff --git a/index.html b/index.html index f2cf615..3aaa7d8 100644 --- a/index.html +++ b/index.html @@ -3,18 +3,18 @@ TCP and UDP Socket API - - + - + - +------------------------------------------------------------------------------> + - - + +

- 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. -

- -
+

+ +
- - + +

Introduction

- 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 @@

Introduction

  • Game servers
  • Peer-to-peer applications
  • Local network multicast service discovery, e.g. UPnP/SSDP and mDNS - - + +
  • - +
    -

    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. -

    - +

    +
    - +

    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]].

    - +
    @@ -270,70 +270,70 @@

    Terminology

    Security and privacy considerations

    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. -

    - - - - + and tcp:, might have to be defined. See address + port vs uri. +

    + + + +

    Navigator Interface

    @@ -344,65 +344,65 @@

    Navigator Interface

    readonly attribute TCPPermission tcpPermission
    The object that exposes permissions for access to the TCPSocket interface. -
    +
    readonly attribute TCPServerPermission tcpServerPermission
    The object that exposes permissions for access to the TCPServerSocket interface. -
    +
    -
    - - + + +

    UDPPermission Interface

    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. -

    - +

    +
    - +
    Promise<TCPUDPPermissionState> hasPermission ()
    - Retrieves the permission state (TCPUDPPermissionState) of the - requesting webapp for creating a UDPSocket object. The + Retrieves the permission state (TCPUDPPermissionState) of the + requesting webapp for creating a UDPSocket object. The method returns a Promise, which is resolved with the permission state as argument.

    This method MUST run the following steps asynchronously:

    1. Create a new Promise, udpPermissionPromise, - return it and run the remaining steps asynchronously.
    2. + return it and run the remaining steps asynchronously.
    3. Retrieve the permission state of the requesting webapp - for creating a UDPSocket object according to the + for creating a UDPSocket object according to the udpPermissionOptions argument.
    4. If there is an error, reject udpPermissionPromise with no arguments and abort the remaining steps.
    5. When the request has been completed, resolve udpPermissionPromise with TCPUDPPermissionState providing the permission - state.
    6. -
    -

    - + state. + +

    +
    - +
    optional UDPPermissionOptions udpPermissionOptions
    Options for the permission state request. If this argument is omitted this is interpreted as described for UDPPermissionOptions - when all dictionary fields are ommitted. -
    - -
    - -
    + when all dictionary fields are ommitted. + + +
    + +
    Promise<void> requestPermission () @@ -410,81 +410,81 @@

    UDPPermission Interface

    Requests permission to create a UDPSocket object. The method returns a Promise, which is resolved if permission was given - and rejected if permission was denied. + and rejected if permission was denied.

    This method MUST run the following steps asynchronously:

    1. Create a new Promise, udpRequestPermissionPromise, - return it and run the remaining steps asynchronously.
    2. -
    3. If the requesting webapp is denied to create a - UDPSocket object that sends UDP packets to the requested + return it and run the remaining steps asynchronously.
    4. +
    5. If the requesting webapp is denied to create a + UDPSocket object that sends UDP packets to the requested remote address and port reject tcpRequestPermissionPromise with DOMException "SecurityError" and abort the remaining steps.
    6. -
    7. If the requesting webapp is denied to create a +
    8. If the requesting webapp is denied to create a UDPSocket object that binds to the requested local address and port reject tcpRequestPermissionPromise with DOMException "SecurityError" and - abort the remaining steps.
    9. -
    10. If the requesting webapp is allowed to create a + abort the remaining steps.
    11. +
    12. If the requesting webapp is allowed to create a UDPSocket object without user interaction, e.g. based - on a prearranged trust relationship or the user has already - granted permission explicitly for this webapp, resolve + on a prearranged trust relationship or the user has already + granted permission explicitly for this webapp, resolve udpRequestPermissionPromise and abort the remaining steps.
    13. Request user consent to create a UDPSocket object.
    14. -
    15. If permission was granted, resolve udpRequestPermissionPromise - and abort the remaining steps.
    16. +
    17. If permission was granted, resolve udpRequestPermissionPromise + and abort the remaining steps.
    18. If permission was not granted, reject udpRequestPermissionPromise - with DOMException "SecurityError".
    19. -
    -

    - + with DOMException "SecurityError". + +

    +
    - +
    optional UDPPermissionOptions udpPermissionOptions
    - Options for the permission request. If this argument is omitted + Options for the permission request. If this argument is omitted this is interpreted as described for UDPPermissionOptions - when all dictionary fields are ommitted. -
    - -
    - -
    - - - -
    - - + when all dictionary fields are ommitted. + + + + + + + + + + +

    TCPPermission Interface

    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. -

    - +

    +
    - +
    Promise<TCPUDPPermissionState> hasPermission ()
    - Retrieves the permission state (TCPUDPPermissionState) of the - requesting webapp for creating a TCPSocket object. The + Retrieves the permission state (TCPUDPPermissionState) of the + requesting webapp for creating a TCPSocket object. The method returns a Promise, which is resolved with the permission state as argument.

    This method MUST run the following steps asynchronously:

    1. Create a new Promise, tcpPermissionPromise, - return it and run the remaining steps asynchronously.
    2. + return it and run the remaining steps asynchronously.
    3. Retrieve the permission state of the requesting webapp for creating a TCPSocket object that connects to the requested remote address and port.
    4. @@ -492,126 +492,126 @@

      TCPPermission Interface

      with no arguments and abort the remaining steps.
    5. When the request has been completed, resolve tcpPermissionPromise with TCPUDPPermissionState providing the permission - state.
    6. -
    -

    - + state. + +

    +
    - +
    optional TCPPermissionOptions tcpPermissionOptions
    Options for the permission state request. If this argument is omitted this is interpreted as described for TCPPermissionOptions - when all dictionary fields are ommitted. -
    - -
    - -
    + when all dictionary fields are ommitted. + + +
    + +
    Promise<void> requestPermission ()
    - Requests permission to create a TCPSocket object that creates - a connection to the requested remoteAddress and remotePort. The method - returns a Promise, which is resolved if permission was given and - rejected if permission was denied. + Requests permission to create a TCPSocket object that creates + a connection to the requested remoteAddress and remotePort. The method + returns a Promise, which is resolved if permission was given and + rejected if permission was denied.

    This method MUST run the following steps asynchronously:

    1. Create a new Promise, tcpRequestPermissionPromise, - return it and run the remaining steps asynchronously.
    2. -
    3. If the requesting webapp is denied to create a + return it and run the remaining steps asynchronously.
    4. +
    5. If the requesting webapp is denied to create a TCPSocket object that connects to the requested remote address and port reject tcpRequestPermissionPromise with DOMException "SecurityError" and abort the remaining steps.
    6. -
    7. If the requesting webapp is allowed to create a +
    8. If the requesting webapp is allowed to create a TCPSocket object that connects to the requested remote - address and port without user interaction, e.g. based on a + address and port without user interaction, e.g. based on a prearranged trust relationship or the user has already granted - permission explicitly for this webapp, resolve + permission explicitly for this webapp, resolve tcpRequestPermissionPromise and abort the remaining steps.
    9. -
    10. Request user consent to create a TCPSocket object +
    11. Request user consent to create a TCPSocket object that connects to the requested remote address and port.
    12. -
    13. If permission was granted, resolve tcpRequestPermissionPromise - and abort the remaining steps.
    14. +
    15. If permission was granted, resolve tcpRequestPermissionPromise + and abort the remaining steps.
    16. If permission was not granted, reject tcpRequestPermissionPromise - with DOMException "SecurityError".
    17. -
    -

    - + with DOMException "SecurityError". + +

    +
    - +
    optional TCPPermissionOptions tcpPermissionOptions
    - Options for the permission request. If this argument is omitted + Options for the permission request. If this argument is omitted this is interpreted as described for TCPPermissionOptions - when all dictionary fields are ommitted. -
    - -
    - -
    - - - -
    - - + when all dictionary fields are ommitted. + + + + + + + + + + +

    TCPServerPermission Interface

    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. -

    - +

    +
    - +
    Promise<TCPUDPPermissionState> hasPermission ()
    - Retrieves the permission state (TCPUDPPermissionState) of the - requesting webapp for creating a TCPServerSocket object. + Retrieves the permission state (TCPUDPPermissionState) of the + requesting webapp for creating a TCPServerSocket object. The method returns a Promise, which is resolved with the permission state as argument.

    This method MUST run the following steps asynchronously:

    1. Create a new Promise, tcpServerPermissionPromise, - return it and run the remaining steps asynchronously.
    2. + return it and run the remaining steps asynchronously.
    3. Retrieve the permission state of the requesting webapp - for creating a TCPServerSocket object according to the + for creating a TCPServerSocket object according to the tcpServerPermissionOptions argument.
    4. If there is an error, reject tcpServerPermissionPromise with no arguments and abort the remaining steps.
    5. When the request has been completed, resolve tcpServerPermissionPromise with TCPUDPPermissionState providing the permission - state.
    6. -
    -

    - + state. + +

    +
    - +
    optional TCPServerPermissionOptions tcpServerPermissionOptions
    Options for the permission state request. If this argument is omitted this is interpreted as described for - TCPServerPermissionOptions when all dictionary fields are - omitted. -
    - -
    - -
    + TCPServerPermissionOptions when all dictionary fields are + omitted. + + +
    + +
    Promise<void> requestPermission () @@ -619,105 +619,101 @@

    TCPServerPermission Interface

    Requests permission to create a TCPServerSocket object. The method returns a Promise, which is resolved if permission was given - and rejected if permission was denied. + and rejected if permission was denied.

    This method MUST run the following steps asynchronously:

    1. Create a new Promise, tcpServerRequestPermissionPromise, - return it and run the remaining steps asynchronously.
    2. -
    3. If the requesting webapp is denied to create a + return it and run the remaining steps asynchronously.
    4. +
    5. If the requesting webapp is denied to create a TCPServerSocket object that binds to the requested local address and port reject tcpServerRequestPermissionPromise with DOMException "SecurityError" and - abort the remaining steps.
    6. -
    7. If the requesting webapp is allowed to create a + abort the remaining steps.
    8. +
    9. If the requesting webapp is allowed to create a TCPServerSocket object without user interaction, e.g. based - on a prearranged trust relationship or the user has already - granted permission explicitly for this webapp, resolve - 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.
    10. Request user consent to create a TCPServerSocket object.
    11. -
    12. If permission was granted, resolve tcpServerRequestPermissionPromise - and abort the remaining steps.
    13. +
    14. If permission was granted, resolve tcpServerRequestPermissionPromise + and abort the remaining steps.
    15. If permission was not granted, reject tcpServerRequestPermissionPromise - with DOMException "SecurityError".
    16. -
    -

    - + with DOMException "SecurityError". + +

    +
    - +
    optional TCPServerPermissionOptions tcpServerPermissionOptions
    - Options for the permission request. If this argument is omitted + Options for the permission request. If this argument is omitted this is interpreted as described for TCPServerPermissionOptions - when all dictionary fields are ommitted. -
    - -
    - -
    - - - -
    - - + when all dictionary fields are ommitted. + + + + + + + + + + +

    Interface UDPSocket

    -

    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); + ); -
    - +
    -
    + class="idl">
    readonly attribute DOMString? localAddress
    -
    The IPv4/6 address of the local interface, e.g. wifi or 3G, that the - UDPSocket object is bound to. Can be set by the constructor's - 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.
    - +
    The IPv4/6 address of the local interface, e.g. wifi or 3G, that the + UDPSocket object is bound to. Can be set by the constructor's + 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.
    +
    readonly attribute unsigned short? localPort
    -
    The local port that the UDPSocket object is bound to. Can be set by +
    The local port that the UDPSocket object is bound to. Can be set by the 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.
    + user agent binds the socket to an ephemeral local port decided by + the system and this attribute is null.
    readonly attribute DOMString? remoteAddress
    -
    The default remote host name or IPv4/6 address that is used for +
    The default remote host name or IPv4/6 address that is used for subsequent send() calls. Null if not stated by the options argument - of the constructor.
    - + of the constructor. +
    readonly attribute unsigned short? remotePort
    The default remote port that is used for subsequent send() calls. - Null if not stated by the options argument of the constructor
    - + Null if not stated by the options argument of the constructor +
    readonly attribute boolean addressReuse
    -
    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.
    - +
    readonly attribute boolean loopback
    -
    Only applicable for multicast. 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.
    - +
    Only applicable for multicast. 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.
    +
    readonly attribute SocketReadyState readyState
    -
    The state of the UDP Socket object. A UDP Socket object can be in "open" - "opening" or "closed" states. See enum SocketReadyState for details.
    - +
    The state of the UDP Socket object. A UDP Socket object can be in "open" + "opening" or "closed" states. See enum SocketReadyState for details.
    +
    readonly attribute Promise opened
    -
    Detects the result of the UDP socket creation attempt. Returns - the openedPromise that was created in the - UDPSocket constructor. -
    - +
    Detects the result of the UDP socket creation attempt. Returns + the openedPromise that was created in the + UDPSocket constructor. +
    +
    readonly attribute Promise closed
    -
    Detects when the UDP socket has been closed, either cleanly by - the webapp calling close()) or +
    Detects when the UDP socket has been closed, either cleanly by + the webapp calling close()) or through an error situation, e.g. network contact lost. - Returns the closedPromise that was created - in the UDPSocket constructor. -
    - + Returns the closedPromise that was created + in the UDPSocket constructor. + +
    readonly attribute ReadableStream readable
    -
    The object that represents the UDP socket's source of data, from which - you can read. [[!STREAMS]]
    - +
    The object that represents the UDP socket's source of data, from which + you can read. [[!STREAMS]]
    +
    readonly attribute WriteableStream writeable
    -
    The object that represents the UDP socket's destination for data, - into which you can write. [[!STREAMS]]
    +
    The object that represents the UDP socket's destination for data, + into which you can write. [[!STREAMS]]
    Promise close()
    -
    -

    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.

    +
    +
    void joinMulticast()
    -
    -

    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).

    +
    - +
    DOMString multicastGroupAddress
    - The multicast group address. -
    - -
    - -
    - + The multicast group address. + + +
    + + +
    void leaveMulticast()
    -
    -

    Leaves a multicast group membership identified by the given address.

    - +
    +

    Leaves a multicast group membership identified by the given address.

    +
    - +
    DOMString multicastGroupAddress
    - The multicast group address. -
    - + The multicast group 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:

    1. Create a new UDPSocket object ("mySocket"). -
    2. If the webapp does not have permission to create a +
    3. If the webapp does not have permission to create a UDPSocket object according to the options argument then throw DOMException "SecurityError" and - abort the remaining steps. -
    4. If the 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. +
    5. If the 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. -
    6. If the 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. +
    7. If the 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. -
    8. If the 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. +
    9. If the options argument's localAddress + member is present and the options argument's + remoteAddress member is present, execute the following step:
        -
      • If the 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 +
    10. If the 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:
        -
      • If the 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: +
    11. If the 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:
      1. Use the routing table to determine the local interface(s) that - 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 + 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. -
      2. If the routing table states that more than one local interface - can be used to send datagrams to the selected - 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 +
      3. If the routing table states that more than one local interface + can be used to send datagrams to the selected + 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. -
      4. Set the mySocket.localAddress attribute to the - local address that the socket is bound to. -
      - Else, i.e. the options argument's localAddress - member is absent, and the options argument's - remoteAddress member is absent, execute the following - step: +
    12. Set the mySocket.localAddress attribute to the + local address that the socket is bound to. +
    + Else, i.e. the options argument's localAddress + member is absent, and the options argument's + remoteAddress member is absent, execute the following + step: -
  • If the 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. -
  • Set the 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. -
  • If the 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. -
  • Set the mySocket.readyState attribute to "opening". -
  • Create a new promise, "openedPromise", and store - it so it can later be returned by the opened - property. -
  • Create a new promise, "closedPromise", and store - it so it can later be returned by the closed - property and the close method. - -
  • Let the 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 + +
  • If the 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. +
  • Set the 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. +
  • If the 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. +
  • Set the mySocket.readyState attribute to "opening". +
  • Create a new promise, "openedPromise", and store + it so it can later be returned by the opened + property. +
  • Create a new promise, "closedPromise", and store + it so it can later be returned by the closed + property and the close method. + +
  • Let the 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: - + +
  • Let the 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: - -
  • - - +

    + + + +

    Interface TCPSocket

    -

    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); - ); -
    - -
    + +
    - + class="idl"> +
    readonly attribute DOMString remoteAddress
    -
    The host name or IPv4/6 address of the peer as stated by the - remoteAddress argument in the constructor.
    - +
    The host name or IPv4/6 address of the peer as stated by the + remoteAddress argument in the constructor.
    +
    readonly attribute unsigned short remotePort
    -
    The port of the peer as stated by the remotePort argument in the - constructor.
    +
    The port of the peer as stated by the remotePort argument in the + constructor.
    readonly attribute DOMString localAddress
    -
    The IPv4/6 address of the local interface, e.g. wifi or 3G, that the +
    The IPv4/6 address of the local interface, e.g. wifi or 3G, that the TCPSocket object is bound to. Can be set by the 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.
    - + 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. +
    readonly attribute unsigned short localPort
    -
    The local port that the TCPSocket object is bound to. Can be set by +
    The local port that the TCPSocket object is bound to. Can be set by the options argument in the constructor. If not set the - user agent binds the socket to an ephemeral local port decided by - the system.
    - + user agent binds the socket to an ephemeral local port decided by + the system. +
    readonly attribute boolean addressReuse
    -
    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.
    +
    readonly attribute boolean noDelay
    -
    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.
    +
    readonly attribute SocketReadyState readyState
    -
    The state of the TCP Socket object. See enum SocketReadyState for - details.
    - +
    The state of the TCP Socket object. See enum SocketReadyState for + details.
    +
    readonly attribute Promise opened
    -
    Detects the result of the TCP connection attempt with the remote - peer. Returns the openedPromise that was created - in the TCPSocket constructor. -
    - +
    Detects the result of the TCP connection attempt with the remote + peer. Returns the openedPromise that was created + in the TCPSocket constructor. +
    +
    readonly attribute Promise closed
    -
    Detects when the TCP connection has been closed, either cleanly - (initiated either by the server, or by the client webapp +
    Detects when the TCP connection has been closed, either cleanly + (initiated either by the server, or by the client webapp calling close()) or through an error situation. - Returns the closedPromise that was created - in the TCPSocket constructor. -
    - + Returns the closedPromise that was created + in the TCPSocket constructor. + +
    readonly attribute ReadableStream readable
    -
    The object that represents the TCP socket's source of data, from which - you can read. [[!STREAMS]]
    - +
    The object that represents the TCP socket's source of data, from which + you can read. [[!STREAMS]]
    +
    readonly attribute WriteableStream writeable
    -
    The object that represents the TCP socket's destination for data, - into which you can write. [[!STREAMS]]
    +
    The object that represents the TCP socket's destination for data, + into which you can write. [[!STREAMS]]
    Promise close()
    -
    -

    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.

    +
    +
    void halfClose()
    -
    -

    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:

    1. Create a new TCPSocket object ("mySocket"). -
    2. If the webapp does not have permission to create a TCPSocket +
    3. If the webapp does not have permission to create a TCPSocket object that connects to the 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.
    4. If the 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. -
    5. If the options argument's localAddress +
    6. If the 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.
      - Otherwise, if the 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:
      1. Use the routing table to determine the local interface(s) that - 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 + 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. -
      2. If the routing table states that more than one local interface +
      3. If the routing table states that more than one local interface can be used to connect to the selected 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. -
      4. Set the mySocket.localAddress attribute to the - local address that the socket is bound to. -
      -
    7. If the 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. -
    8. Set the mySocket.addressReuse attribute to the value - of the options argument's addressReuse - member if it is present or to true if the options +
    9. Set the mySocket.localAddress attribute to the + local address that the socket is bound to. +
    +
  • If the 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. +
  • Set the 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. -
  • Set the 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. -
  • Set the mySocket.readyState attribute to "opening". -
  • Create a new promise, "openedPromise", and store - it so it can later be returned by the opened - property. -
  • Create a new promise, "closedPromise", and store - it so it can later be returned by the closed - property and the close method. - -
  • Let the 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 +
  • Set the 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. +
  • Set the mySocket.readyState attribute to "opening". +
  • Create a new promise, "openedPromise", and store + it so it can later be returned by the opened + property. +
  • Create a new promise, "closedPromise", and store + it so it can later be returned by the closed + property and the close method. + +
  • Let the 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: - + +
  • Let the 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: - - + +
  • Return the newly created TCPSocket object ("mySocket") to the webapp. -

    - -

    The close() method when invoked MUST run the +

    + +

    The close() method when invoked MUST run the following steps:

      -
    1. Call mysocket.readable.cancel(reason). (Reason codes TBD.) +
    2. Call mysocket.readable.cancel(reason). (Reason codes TBD.)
    3. Return closedPromise.
    -

    - -

    The halfClose() method when invoked MUST run the +

    + +

    The halfClose() method when invoked MUST run the following steps:

      -
    1. Call mysocket.writeable.close(). +
    2. Call mysocket.writeable.close().
    -

    - +

    + -
  • - - + + +

    Interface TCPServerSocket

    -

    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); + ); + +
    - - -
    - + class="idl"> +
    readonly attribute DOMString localAddress
    -
    The IPv4/6 address of the interface, e.g. wifi or 3G, that the - TCPServer Socket object is bound to. Can be set by the - 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. -
    - +
    The IPv4/6 address of the interface, e.g. wifi or 3G, that the + TCPServer Socket object is bound to. Can be set by the + 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. +
    +
    readonly attribute unsigned short localPort
    -
    The local port that the TCPServerSocket object is bound to. Can be - set by the 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. -
    - +
    The local port that the TCPServerSocket object is bound to. Can be + set by the 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. +
    +
    readonly attribute boolean addressReuse
    -
    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.
    +
    readonly attribute SocketReadyState readyState
    -
    The state of the TCP server object. A TCP server socket object can - be in "open", "opening" or "closed" states. See enum SocketReadyState - for details.
    - +
    The state of the TCP server object. A TCP server socket object can + be in "open", "opening" or "closed" states. See enum SocketReadyState + for details.
    +
    readonly attribute Promise opened
    -
    Detects the result of the TCP server socket opening process when - the socket is ready to receive connection attempts from clients. - Returns the openedPromise that was created in the - TCPServerSocket constructor. -
    - +
    Detects the result of the TCP server socket opening process when + the socket is ready to receive connection attempts from clients. + Returns the openedPromise that was created in the + TCPServerSocket constructor. +
    +
    readonly attribute Promise closed
    -
    Detects when the TCP server socket been closed, either cleanly - by the webapp calling close()) or through - an error situation. Returns the closedPromise that - was created in the TCPSocket constructor. -
    - +
    Detects when the TCP server socket been closed, either cleanly + by the webapp calling close()) or through + an error situation. Returns the closedPromise that + was created in the TCPSocket constructor. +
    +
    Promise listen()
    -
    -

    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.

    -
    + DOMException "NetworkError" if there is an error on + an incoming connection attempt.

    +
    Promise close()
    -
    -

    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:

    1. Create a new TCPServerSocket object ("myServerSocket"). -
    2. If the webapp does not have permission to create a +
    3. If the webapp does not have permission to create a TCPServerSocket object according to the options argument then throw DOMException "SecurityError" and - abort the remaining steps. -
    4. If the options argument's localAddress - member is absent the server will accept connections directed to + abort the remaining steps. +
    5. If the 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.
    6. If the 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.
    7. Set the 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. -
    8. Set the myServerSocket.readyState attribute to "opening". -
    9. Create a new promise, "openedPromise", and store - it so it can later be returned by the opened - property. -
    10. Create a new promise, "closedPromise", and store - it so it can later be returned by the closed - property and the close method. -
    11. Return the newly created TCPServerSocket object to the + options argument's addressReuse member + if it is present or to true if the options + argument's addressReuse member is not present. +
    12. Set the myServerSocket.readyState attribute to "opening". +
    13. Create a new promise, "openedPromise", and store + it so it can later be returned by the opened + property. +
    14. Create a new promise, "closedPromise", and store + it so it can later be returned by the closed + property and the close method. +
    15. Return the newly created TCPServerSocket object to the webapp.
    -

    - -

    The close method when invoked MUST run the +

    + +

    The close method when invoked MUST run the following steps:

      -
    1. If a TCP connection setup is in progress the connection setup is +
    2. If a TCP connection setup is in progress the connection setup is finalized according to the descriptions below. -
    3. Stop listening to further connection attempts from clients. +
    4. Stop listening to further connection attempts from clients.
    5. Set the myServerSocket.readyState attribute to "closed". -
    6. Resolve closedPromise with - undefined. +
    7. Resolve closedPromise with + undefined.
    -

    - -

    The listen method when invoked MUST run the +

    + +

    The listen method when invoked MUST run the following steps:

    1. If myServerSocket.readyState attribute is"closed" then - throw DOMException "InvalidStateError" and abort the + throw DOMException "InvalidStateError" and abort the remaining steps.
    2. Create a new promise, "connectionPromise". -
    3. Start listening for connections on the specified local port - and address. Return connectionPromise. +
    4. Start listening for connections on the specified local port + and address. Return 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: - +

      -
    1. Change the myServerSocket.readyState attribute's value to "open". -
    2. Resolve openedPromise with undefined. +
    3. Change the myServerSocket.readyState attribute's value to "open". +
    4. Resolve 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: - +

      -
    1. Change the myServerSocket.readyState attribute's value to - "closed". -
    2. Reject openedPromise with DOMException - "NetworkError". -
    3. Reject closedPromise with DOMException - "NetworkError". -
    -

    - -

    When there is an error on an established TCP server socket +

  • Change the myServerSocket.readyState attribute's value to + "closed". +
  • Reject openedPromise with DOMException + "NetworkError". +
  • Reject 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: - +

      -
    1. Change the myServerSocket.readyState attribute's value to - "closed". -
    2. Reject closedPromise with DOMException - "NetworkError". -
    -

    - -

    Upon a new successful connection to the TCP server socket the +

  • Change the myServerSocket.readyState attribute's value to + "closed". +
  • Reject closedPromise with DOMException + "NetworkError". + +

    + +

    Upon a new successful connection to the TCP server socket the user agent MUST run the following steps: - +

    1. Let socket be a new instance of TCPSocket. -
    2. Set the remoteAddress attribute of socket - to the IPv4/6 address of the peer. -
    3. Set the remotePort attribute of socket - to the source port of the of the peer. -
    4. Set the localAddress attribute of socket - to the used local IPv4/6 address. -
    5. Set the localPort attribute of socket to - the used local source port. -
    6. Set the readyState attribute of socket - to "open". -
    7. Set the bufferedAmount attribute of socket - to 0. +
    8. Set the remoteAddress attribute of socket + to the IPv4/6 address of the peer. +
    9. Set the remotePort attribute of socket + to the source port of the of the peer. +
    10. Set the localAddress attribute of socket + to the used local IPv4/6 address. +
    11. Set the localPort attribute of socket to + the used local source port. +
    12. Set the readyState attribute of socket + to "open". +
    13. Set the bufferedAmount attribute of socket + to 0.
    14. Resolve 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: - +

      -
    1. Reject connectionPromise with DOMException - "NetworkError". +
    2. Reject connectionPromise with DOMException + "NetworkError".
    -

    +

    -
  • - - + + +

    Dictionary UDPMessage

    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.

    + class="idl">
    ArrayBuffer data
    -
    Received UDP data or UDP data to send.
    +
    Received UDP data or UDP data to send.
    DOMString remoteAddress
    The address of the remote machine.
    unsigned short remotePort
    -
    The port of the remote machine.
    -
    - -
    - - +
    The port of the remote machine.
    + + + + +

    Dictionary UDPOptions

    - 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. -

    +

    - + class="idl"> +
    DOMString localAddress
    -
    The IPv4/6 address of the local interface, e.g. wifi or 3G, that the - UDPSocket object is bound to. If the field is omitted, 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 if this member is present. Else the - UDPSocket is unbound to a local interface.
    - +
    The IPv4/6 address of the local interface, e.g. wifi or 3G, that the + UDPSocket object is bound to. If the field is omitted, 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 if this member is present. Else the + UDPSocket is unbound to a local interface.
    +
    unsigned short localPort
    -
    The local port that the UDPSocket object is bound to. If the the field - is omitted, the user agent binds the socket to a an ephemeral local - port decided by the system.
    +
    The local port that the UDPSocket object is bound to. If the the field + is omitted, the user agent binds the socket to a an ephemeral local + port decided by the system.
    DOMString remoteAddress
    -
    When present the default remote host name or IPv4/6 address - that is used for subsequent send() calls.
    - +
    When present the default remote host name or IPv4/6 address + that is used for subsequent send() calls.
    +
    unsigned short remotePort
    -
    When present the default remote port that is used for subsequent - send() calls.
    - +
    When present the default remote port that is used for subsequent + send() calls.
    +
    boolean addressReuse
    -
    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.
    - +
    boolean loopback
    -
    Only applicable for multicast. true means that sent - multicast data is looped back to the sender. - Default is false.
    - -
    - -
    - - +
    Only applicable for multicast. true means that sent + multicast data is looped back to the sender. + Default is false.
    + + + + + +

    Dictionary TCPOptions

    - 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. +

    - + class="idl"> +
    DOMString localAddress
    -
    The IPv4/6 address of the local interface, e.g. wifi or 3G, that the - TCPSocket object is bound to. If the field is omitted, 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.
    - +
    The IPv4/6 address of the local interface, e.g. wifi or 3G, that the + TCPSocket object is bound to. If the field is omitted, 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.
    +
    unsigned short localPort
    -
    The local port that the TCPSocket object is bound to. If the the field - is omitted, the user agent binds the socket to an ephemeral local port - decided by the system.
    - +
    The local port that the TCPSocket object is bound to. If the the field + is omitted, the user agent binds the socket to an ephemeral local port + decided by the system.
    +
    boolean addressReuse
    -
    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. -
    - + +
    boolean noDelay
    -
    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.
    +
    boolean useSecureTransport
    -
    true if socket uses SSL or TLS. Default is +
    true if socket uses SSL or TLS. Default is false.
    - +
    TCPKeepAliveOptions tcpKeepAliveOptions
    -
    States the "keepalive" options for the TCPSocket. TCP "keepalive" - causes a packet (called a 'keepalive probe') to be sent to the remote - system if a long time passes with no data or acknowledgement packets - received. This packet is designed to provoke an ACK response from the - peer. This enables detection of a peer which has become unreachable - (e.g. powered off or disconnected from the net). If this field - is omitted keepalive probes will not be sent.
    - +
    States the "keepalive" options for the TCPSocket. TCP "keepalive" + causes a packet (called a 'keepalive probe') to be sent to the remote + system if a long time passes with no data or acknowledgement packets + received. This packet is designed to provoke an ACK response from the + peer. This enables detection of a peer which has become unreachable + (e.g. powered off or disconnected from the net). If this field + is omitted keepalive probes will not be sent.
    +
    unsigned long tcpKeepAliveSparseIntvl
    The time (in seconds) between individual keepalive probes. Default - is 600 seconds (10 minutes).
    - - -
    - + is 600 seconds (10 minutes). + + + +

    - Use of secure transport needs more investigation -

    -
    - - + Use of secure transport needs more investigation +

    + + +

    Dictionary TCPServerOptions

    - 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. -

    +

    - +
    DOMString localAddress
    -
    The IPv4/6 address of the interface, e.g. wifi or 3G, that the - TCPServerSocket object is bound to. If the field is omitted, the - user agent binds the server socket to the IPv4/6 address of the - default local interface.
    - +
    The IPv4/6 address of the interface, e.g. wifi or 3G, that the + TCPServerSocket object is bound to. If the field is omitted, the + user agent binds the server socket to the IPv4/6 address of the + default local interface.
    +
    unsigned short localPort
    -
    The local port that the TCPServerSocket object is bound to. If the - the field is omitted, the user agent binds the socket to an ephemeral - local port decided by the system.
    - +
    The local port that the TCPServerSocket object is bound to. If the + the field is omitted, the user agent binds the socket to an ephemeral + local port decided by the system.
    +
    boolean addressReuse
    -
    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.
    +
    boolean useSecureTransport
    -
    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 +

    + +
    - - - +

    Dictionary UDPPermissionOptions

    - 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. -

    + and requestPermission methods. All fields are optional. +

    - + class="idl"> +
    DOMString localAddress
    -
    The local interface that the webapp requests permission for the - UDPSocket object to be bound to. If the field is omitted the - webapp does not request permission to use any specific local - interface, i.e. the user agent selects local interface.
    - +
    The local interface that the webapp requests permission for the + UDPSocket object to be bound to. If the field is omitted the + webapp does not request permission to use any specific local + interface, i.e. the user agent selects local interface.
    +
    unsigned short localPort
    The local port that the webapp requests permission for the UDPSocket object to be bound to. If the field is omitted the webapp does not request permission to use any specific local - port, i.e. the user agent selects local port.
    + port, i.e. the user agent selects local port.
    DOMString remoteAddress
    -
    The host name or IPv4/6 address the webapp requests permission +
    The host name or IPv4/6 address the webapp requests permission for the UDPSocket object to send UDP packets to. If the field - is omitted it means that the webapp requests permission - for the UDPSocket object to send UDP packets to any peer.
    - + is omitted it means that the webapp requests permission + for the UDPSocket object to send UDP packets to any peer. +
    unsigned short remotePort
    The port of the peer the webapp requests permission for the UDPSocket object to send UDP packets to. If the field is omitted it means that the webapp requests permission for - the UDPSocket object to send UDP packets to any port.
    - -
    - -
    - - + the UDPSocket object to send UDP packets to any port. + + + + + +

    Dictionary TCPPermissionOptions

    - 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. -

    + and requestPermission methods. All fields are optional. +

    + class="idl">
    DOMString remoteAddress
    -
    The host name or IPv4/6 address the webapp requests permission +
    The host name or IPv4/6 address the webapp requests permission for the TCPSocket object to connect to. If the field - is omitted it means that the webapp requests permission - for the TCPSocket object to connect to any peer.
    - + is omitted it means that the webapp requests permission + for the TCPSocket object to connect to any peer. +
    unsigned short remotePort
    The port of the peer the webapp requests permission for the TCPSocket object to connect to. If the field is omitted it means that the webapp requests permission for - the TCPSocket object to connect to any port.
    - -
    - -
    - - + the TCPSocket object to connect to any port. + + + + + +

    Dictionary TCPServerPermissionOptions

    - 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. -

    + All fields are optional. +

    - + class="idl"> +
    DOMString localAddress
    -
    The local interface that the webapp requests permission for the +
    The local interface that the webapp requests permission for the TCPServerSocket object to be bound to. If the field is omitted - the webapp does not request permission to use any specific local - interface, i.e. the user agent selects local interface.
    - + the webapp does not request permission to use any specific local + interface, i.e. the user agent selects local interface. +
    unsigned short localPort
    The local port that the webapp requests permission for the TCPServerSocket object to be bound to. If the field is omitted - the webapp does not request permission to use any specific - local port, i.e. the user agent selects local port.
    - -
    - -
    - - + the webapp does not request permission to use any specific + local port, i.e. the user agent selects local port. + + + + + +

    Enums

    - +
    - +

    TCPUDPPermissionState

    - +
    granted
    The webapp has permission to use the requested interface.
    denied
    -
    The webapp has been denied permission to use the requested +
    The webapp has been denied permission to use the requested interface.
    prompt
    -
    The webapp needs to request permission to use the - requested interface by calling requestPermission.
    -
    -
    - +
    The webapp needs to request permission to use the + requested interface by calling requestPermission.
    + +
    +
    - +

    SocketReadyState

    - +
    opening
    -
    The socket is in opening state, i.e. availability of local address/port - is being checked, network status is being checked, etc. For TCP a +
    The socket is in opening state, i.e. availability of local address/port + is being checked, network status is being checked, etc. For TCP a connection with a remote peer has not yet been established.
    open
    -
    The socket is ready to use to send and received data. For TCP a +
    The socket is ready to use to send and received data. For TCP a connection with a remote peer has been established.
    closing
    -
    Only used for TCP sockets. The TCP connection is going through +
    Only used for TCP sockets. The TCP connection is going through the closing handshake, or the close() method has been invoked.
    closed
    -
    The socket is closed and can not be use to send and received data. - For TCP the connection has been closed or could not be opened.
    +
    The socket is closed and can not be use to send and received data. + For TCP the connection has been closed or could not be opened.
    halfclosed
    Only used for TCP sockets. The TCP connection has been "halfclosed" - by the webapp, which means that it is not possible to send data - but it is still possible to receive.
    -
    -
    + by the webapp, which means that it is not possible to send data + but it is still possible to receive. + +
    - +

    TCPKeepAliveOptions

    - +
    off
    Don't use TCP keep-alives. This is the defult.
    frequent-then-sparse
    -
    Keep-alive probes every 10s for first minute, then send with +
    Keep-alive probes every 10s for first minute, then send with "tcpKeepAliveSparseIntvl" after that.
    sparse
    -
    Keep-alive probe sent with "tcpKeepAliveSparseIntvl".
    -
    -
    - - - - +
    Keep-alive probe sent with "tcpKeepAliveSparseIntvl".
    + + + + + +

    Acknowledgements

    - 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.