WebSync Documentation - Frozen Mountain

WebSync Version 2 Docs


Note: this documentation is for WebSync 2 only.

You probably are looking for our WebSync 3 documentation.


WebSync proxies can intercept and pre-process client requests. They are intended for server-side implementation of custom application logic.

Overview

Proxies can be used to intercept and pre-process messages going to a WebSync server. Both the JavaScript and .NET clients support redirecting method calls to a proxy instead of the default WebSync handler.

Why proxy?

Request proxies can be used to implement custom functionality that would otherwise be impossible to achieve. By gaining full access to the client messages before they reach the WebSync servers, proxies can act as gateways that enforce security, persist data, authorize behaviour, manage contacts... and the list goes on.

How does it work?

Setting up a proxy is simple. Create a new page or script on your site, and direct your client method calls there. A proxy does the following:

  1. Receive client messages in JSON format.
  2. Read and perhaps modify the messages.
  3. Send the messages to the WebSync handler.
  4. Receive the responses from the WebSync handler.
  5. Send the responses to the client.

The Proxy class in the WebSync On-Demand .NET library contains all you need to get going quickly and easily.

What can I modify?

Within the proxy, you can modify the key and/or messages before the request completes its journey to a WebSync server.

How do I enforce security?

The premise is simple. Enforce security by modifying the key and making an action private.

Proxies can be configured with a key parameter. The proxy will use this key when talking to the WebSync servers. By using your private key here, you can ensure that any actions going through your proxy will be private. You can then configure an action to require your private key in the Portal.

So long as you keep your private key private, any requests that do not go through your proxy will be denied. Your proxy can then serve as a gateway, determining which requests are allowed and which are not.

How do I deny a request?

To deny a request, simply set the successful property of the message to false before passing it along to WebSync. We'll take care of formatting a proper Bayeux response that the client can understand.

You can also optionally set the error property to a custom error message you want delivered to the client.

.NET Proxy

Before you can use the .NET proxy, if you haven't already:

  1. Download the latest copy of WebSync On-Demand .NET.
  2. Add a reference to the downloaded library to your project.

Now, just create a blank page and invoke the proxy in code:

// WebSync On-Demand Only
Proxy.Invoke(new ProxyCallback((args) =>
{
    // do work here
}), "22222222-2222-2222-2222-222222222222"); // alter the domain key here

// WebSync Server Only
Proxy.Invoke(new ProxyCallback((args) =>
{
    // do work here
}), null, "http://mydomain.com/request.ashx"); // replace with your request handler

Contact us if you are interested in using a proxy for another language.

PHP Proxy

Before you can use the PHP proxy, if you haven't already:

  1. Download the latest copy of WebSync On-Demand PHP.
  2. Include a reference to 'Proxy.php' in your script.

Now, just create a blank page and invoke the proxy in code:

function callback($args) {
    // do work here
}

// WebSync On-Demand Only
Proxy::invoke("callback",
    "22222222-2222-2222-2222-222222222222" // alter the domain key here
);

// WebSync Server Only
Proxy::invoke("callback",
    null, "http://mydomain.com/request.ashx" // replace with your request handler
);

Contact us if you are interested in using a proxy for another language.

Message Structure

The messages the proxy will receive are structured in accordance with the Bayeux protocol. The most important message properties to consider are:

  • channel (string)
    The name of the channel to which this message is being sent.

    The client method invoked can be inferred from the channel name.

    If the channel is... then the method is a...
    /meta/handshake connect.
    /meta/subscribe subscribe.
    /meta/unsubscribe unsubscribe.
    /meta/disconnect disconnect.
    anything else publish.
  • clientId (string)
    The unique identifier for the client sending this request.
  • successful (boolean)
    Whether or not the request is successful.

    If set to false by a proxy, the WebSync handler will consider the request denied and respond accordingly.

  • error (string)
    The error message if the request is unsuccessful.
  • data (object)
    The data to be published.
  • subscription (string or string[])
    The name(s) of the channel(s) to subscribe or unsubscribe.

Serialization

Messages are always serialized to and deserialized from JSON.

Most languages include support for JSON serialization. Refer to your language documentation for more details.

Use Cases

The extent to which request proxies can be used to expand your application and extend its usability is virtually unlimited. To get your imagination going, we have put together a few examples.

Since proxies are most useful for WebSync On-Demand, we assume an On-Demand customer's perspective for these examples.

Client Authentication

Authenticating clients is one of the most common needs in web applications. WebSync makes it easy.

Before you can authenticate, you must configure your domain to only allow Connect calls from private keys. Your domain's private configuration can be managed in the Portal.

Create the proxy as follows (say at mydomain.com/proxy):

protected void Page_Load(object sender, EventArgs e)
{
    Proxy.Invoke(new ProxyCallback((args) =>
    {
        // authenticate from local database (write this method)
        if (!Authenticate(args.Context))
        {
            foreach (Message m in args.Messages)
            {
                // authentication failed
                // all messages in the request are denied
                m.Successful = false;
                m.Error = "Authentication failed.";
            }
        }
    }), "22222222-2222-2222-2222-222222222222"); // use your private key
}

Now configure the client to connect using the proxy (example is for JavaScript):

fm.websync.client.connect({
    url: 'http://mydomain.com/proxy'
});

That's it!

But wait! What if you don't want to use sessions? Or what if your proxy is on a different domain?

No problem. You can pass in extra data using the ext property in the client method calls. Change the proxy to read:

protected void Page_Load(object sender, EventArgs e)
{
    Proxy.Invoke(new ProxyCallback((args) =>
    {
        foreach (Message m in args.Messages)
        {
            // authenticate from local database (write this method)
            if (!Authenticate(m.Ext))
            {
                // authentication failed
                // all messages in the request are denied
                m.Successful = false;
                m.Error = "Authentication failed.";
            }
        }
    }), "22222222-2222-2222-2222-222222222222"); // use your private key
}

And change the client to read:

fm.websync.client.connect({
    url: 'http://mydomain.com/proxy',
    ext: { // your custom data goes here
        user: 'jsmith',
        id: '39ce7e2a8573b41ce73b5ba41617f8f7'
    }
});

Publish Authorization

Authorizing publications is simple with a proxy. The same procedure applies for authorizing any client action.

Before you can authorize publications, you must configure your domain to only allow Publish calls from private keys. Your domain's private configuration can be managed in the Portal.

Create the proxy as follows (say at mydomain.com/proxy):

protected void Page_Load(object sender, EventArgs e)
{
    Proxy.Invoke(new ProxyCallback((args) =>
    {
        // authorize from local database (write this method)
        if (!Authorize(args.Context))
        {
            foreach (Message m in args.Messages)
            {
                // authentication failed
                // all messages in the request are denied
                m.Successful = false;
                m.Error = "Authorization failed.";
            }
        }
    }), "22222222-2222-2222-2222-222222222222"); // use your private key
}

Now configure the client to publish using the proxy (example is for JavaScript):

fm.websync.client.publish({
    url: 'http://mydomain.com/proxy'
});

That's it!

As with authentication, if you cannot use sessions, the ext property available in the client method calls can assist you. Change the proxy to read:

protected void Page_Load(object sender, EventArgs e)
{
    Proxy.Invoke(new ProxyCallback((args) =>
    {
        foreach (Message m in args.Messages)
        {
            // authorize from local database (write this method)
            if (!Authorize(m.Ext))
            {
                m.Successful = false;
                m.Error = "Authentication failed.";
            }
        }
    }), "22222222-2222-2222-2222-222222222222"); // use your private key
}

And change the client to read:

fm.websync.client.publish({
    url: 'http://mydomain.com/proxy',
    ext: { // your custom data goes here
        user: 'jsmith',
        id: '39ce7e2a8573b41ce73b5ba41617f8f7'
    }
});

Persisting Data

Another common use case is persisting published data. A typical example would involve collaborative data modification with WebSync, with the data modifications persisting to a local database.

Simply create the proxy as follows (say at mydomain.com/proxy):

protected void Page_Load(object sender, EventArgs e)
{
    Proxy.Invoke(new ProxyCallback((args) =>
    {
        foreach (Message m in args.Messages)
        {
            // persist to local database (write this method)
            Persist(m.Data);
        }
    }));
}

Note that we are not using a private key here. It is not necessary since we are not restricting access.

Now configure the client to publish using the proxy (example is for JavaScript):

fm.websync.client.publish({
    url: 'http://mydomain.com/proxy'
});

That's it!