How to connect with a StreamWebSocket (HTML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

This topic will show you how to send and receive streams of data using StreamWebSocket in a Windows Runtime app.

The StreamWebSocket class provides a stream-based abstraction of the message-based WebSocket protocol. This is useful for scenarios in which large files (such as photos or movies) need to be transferred between a client and server. The server must support the WebSocket protocol. Using StreamWebSocket allows sections of a message to be read with each read operation, rather than requiring the entire message to be read in a single operation (as with MessageWebSocket).

The StreamWebSocket class only supports binary messages. For UTF-8 messages, MessageWebSocket must be used.

Prerequisites

The following examples use JavaScript and are based on the WebSocket sample. For general help creating a Windows Runtime app using JavaScript, see Create your first Windows Runtime app using JavaScript. Additionally, JavaScript promises are used in this topic to complete asynchronous operations. For more information on this programming pattern, see Asynchronous programming in JavaScript using promises.

To ensure your Windows Runtime app is network ready, you must set any network capabilities that are needed in the project Package.appxmanifest file. If your app needs to connect as a client to remote services on the Internet, then the Internet (Client) capability is needed. If the app needs to connect as a client to remote services on a home network or work network, then the Home/Work Networking capability is needed.

Note  On Windows Phone, there is only one network capability (Internet (Client & Server))which enables all network access for the app.

 

For more information, see How to set network capabilities.

Instructions

1. Create a StreamWebSocket object to send and receive data

The code in this section creates a new StreamWebSocket, connects to a WebSocket server, sends data to the server, and listens for a response.

We first validate that the server URI to be used is valid. Then we connect to the WebSocket server using the URI and wait to receive the response from the server.

The input URI address is first checked to make sure that the user passed a valid URI address. This step isn't needed if the app already knows the URI for the WebSocket server.

An exception is thrown when an invalid string for the Uniform Resource Identifier (URI) is passed to the constructor for the Windows.Foundation.Uri object.

In JavaScript, there is no method to try and parse a string to a URI. To catch this exception in that case, use a try/catch block around the code where the URI is constructed.

The sample also checks that the HTTP scheme in the URI is WS or WSS since these are the only schemes supported by a StreamWebSocket.

If we have a valid URI from user input, then the app connects to the WebSocket server and can send and receive data.

Exceptions from network errors (loss of connectivity, connection failures, and HTTP server failures, for example) can happen at any time. These errors result in exceptions being thrown. If not handled by your app, an exception can cause your entire app to be terminated by the runtime. You must write code to handle exceptions when you call most asynchronous network methods. Sometimes when an exception occurs, a network method can be retried to try and resolve the problem. Other times, your app may need to plan to continue without network connectivity using previously cached data. For more information on handling network exceptions, see Handling exceptions in network apps.

Note  You may wish to display messages to the user or write to log that certain events have happened (for example, when a connection is made or when an error occurs). The sample calls a displayStatus function that you would need to implement for your app.

 

Note  The writeOutgoing() and readIncoming() functions to perform the write and read operations will be defined in subsequent steps.

 

  • Open the js folder. Open the .js file you are using and add the following code.

    
    // Define some variables we will use
    var streamWebSocket;
    var dataWriter;
    var dataReader;
    // The data to send
    var data = "Hello World";
    var countOfDataSent;
    var countOfDataReceived;
    
    function start() {
       if (streamWebSocket) {
          // The WebSocket is already running. Go ahead and immediately return,  
          // or display a message that indicates that it is running.
          return;
       }
    
       var webSocket = new Windows.Networking.Sockets.StreamWebSocket();
       webSocket.onclosed = onClosed;
    
       // WebSocket server to test connections
       // If the scheme is wss:, then the server will
       // echo back what it receives
       var uriString = "wss://echo.websocket.org";
    
       // We might get the uriString from the user so
       // we need to check that we have a valid URI
       var serverUri;
       try {
          serverUri = new Windows.Foundation.Uri(uriString);
          }
       catch (Exception) {
          displayStatus("Invalid URI, please re-enter a valid URI.");
          return;
       }
    
       if (serverUri.schemeName != "ws" && serverUri.schemeName != "wss") {
          displayStatus("Only 'ws' and 'wss' schemes supported. Please re-enter URI");
          return;
       }
    
       // Asynchronous networking methods can throw execptions
       webSocket.connectAsync(uri).done(function () {
          diaplayStatus("Connected");
    
          streamWebSocket = webSocket;
          dataWriter = new Windows.Storage.Streams.DataWriter(webSocket.outputStream);
          dataReader = new Windows.Storage.Streams.DataReader(webSocket.inputStream);
          // When buffering, return as soon as any data is available.
          dataReader.inputStreamOptions = Windows.Storage.Streams.InputStreamOptions.partial;
          countOfDataSent = 0;
          countOfDataReceived = 0;
    
          // Continuously send data to the server
          writeOutgoing();
    
          // Continuously listen for a response
          readIncoming();
    
       }, function (error) {
          var errorStatus = Windows.Networking.Sockets.WebSocketError.getStatus(error.number);
          if (errorStatus === Windows.Web.WebErrorStatus.cannotConnect ||
             errorStatus === Windows.Web.WebErrorStatus.notFound ||
             errorStatus === Windows.Web.WebErrorStatus.requestTimeout) {
             displayStatus("Cannot connect to the server");
          } else {
             displayStatus("Failed to connect: " + getError(error));
          }
       });
    }
    

2. Send outgoing data

The code in this section lets your WebSocket object send data to a server.

Note  The writeError() function will be defined in a subsequent step.

 

  • Add the following code to your .js file to define the writeOutgoing() function.

    function writeOutgoing() {
       try {
          var size = dataWriter.measureString(data);
          countOfDataSent += size;
    
          dataWriter.writeString(data);
          dataWriter.storeAsync().done(function () {
             // Add a 1 second delay so the user can see what's going on.
             setTimeout(writeOutgoing, 1000);
          }, writeError);
       }
       catch (error) {
          displayStatus("Sync write error: " + getError(error));
       }
    }
    

3. Read incoming data

The code in this section lets your WebSocket object read data from a server.

Note  The readError() function will be defined in a subsequent step.

 

  • Add the following code to your .js file to define the readIncoming() function.

    
    function readIncoming(args) {
       // Buffer as much data as you require for your protocol.
       dataReader.loadAsync(100).done(function (sizeBytesRead) {
          countOfDataReceived += sizeBytesRead;
    
          var incomingBytes = new Array(sizeBytesRead);
          dataReader.readBytes(incomingBytes);
    
          // Do something with the data.
          // Alternatively you can use DataReader to read out individual booleans,
          // ints, strings, etc.
    
          // Start another read.
          readIncoming();
       }, readError);
    }
    

4. Add error handling code

  • You must write code to handle exceptions when you call most asynchronous network methods. Your exception handler can retrieve more detailed information on the cause of the exception to better understand the failure and make appropriate decisions. For more information, see How to handle exceptions in network apps.

    Add code to your .js file to define writeError() and readError() functions to log write and read errors (or take other actions), respectively. The specific implementation you use may vary.

    
    function writeError(error) {
       // Add your code to handle write errors.
    }
    
    function readError(error) {
       // Add your code to handle read errors.
    }
    

5. Register your callback for the StreamWebSocket.Closed event

When the StreamWebSocket.Closed event occurs, the registered callback is called and receives data from WebSocketClosedEventArgs to close the connection.

  • Add the following code to your .js file.

    function onClosed(args) {
       // You can add code to log or display the code and reason
       // for the closure (stored in args.code and args.reason)
       if (streamWebSocket) {
          streamWebSocket.close();
       }
       streamWebSocket = null;
    }
    

Summary and next steps

In this tutorial, we reviewed how to connect to a WebSocket server and how to send and receive data using a StreamWebSocket.

For a complete sample that demonstrates how to send and receive data with WebSockets, see the WebSocket sample.

Other

Asynchronous programming in JavaScript using promises

Connecting with WebSockets

Create your first Windows Runtime app using JavaScript

How to connect with a MessageWebSocket

How to handle exceptions in network apps

How to set network capabilities

Reference

StreamWebSocket

Windows.Networking.Sockets

Samples

WebSocket sample