All Downloads are FREE. Search and download functionalities are using the official Maven repository.

donky.microsoft.aspnet.signalr.client.transport.ServerSentEventsTransport Maven / Gradle / Ivy

There is a newer version: 2.7.0.3
Show newest version
/*
Copyright (c) Microsoft Open Technologies, Inc.
All Rights Reserved
See License.txt in the project root for license information.
*/

package donky.microsoft.aspnet.signalr.client.transport;

import donky.microsoft.aspnet.signalr.client.SignalRFuture;
import donky.microsoft.aspnet.signalr.client.ConnectionBase;
import donky.microsoft.aspnet.signalr.client.Constants;
import donky.microsoft.aspnet.signalr.client.LogLevel;
import donky.microsoft.aspnet.signalr.client.Logger;
import donky.microsoft.aspnet.signalr.client.http.HttpConnection;
import donky.microsoft.aspnet.signalr.client.http.HttpConnectionFuture.ResponseCallback;
import donky.microsoft.aspnet.signalr.client.http.Request;
import donky.microsoft.aspnet.signalr.client.http.Response;

/**
 * HttpClientTransport implementation over Server Sent Events implementation
 */
public class ServerSentEventsTransport extends HttpClientTransport {

    private static final int SSE_DATA_PREFIX_LENGTH = 6;
    private static final String DATA_INITIALIZED = "data: initialized";
    private static final String END_OF_SSE_MESSAGE = "\n\n";

    private SignalRFuture mConnectionFuture;

    /**
     * Initializes the transport with a logger
     * 
     * @param logger
     *            Logger to log actions
     */
    public ServerSentEventsTransport(Logger logger) {
        super(logger);
    }

    /**
     * Initializes the transport with a logger
     * 
     * @param logger
     *            Logger to log actions
     * @param httpConnection
     *            HttpConnection for the transport
     */
    public ServerSentEventsTransport(Logger logger, HttpConnection httpConnection) {
        super(logger, httpConnection);
    }

    @Override
    public String getName() {
        return "serverSentEvents";
    }

    @Override
    public boolean supportKeepAlive() {
        return true;
    }

    @Override
    public SignalRFuture start(ConnectionBase connection, ConnectionType connectionType, final DataResultCallback callback) {
        log("Start the communication with the server", LogLevel.Information);
        String url = connection.getUrl() + (connectionType == ConnectionType.InitialConnection ? "connect" : "reconnect")
                + TransportHelper.getReceiveQueryString(this, connection);

        Request get = new Request(Constants.HTTP_GET);

        get.setUrl(url);
        get.setHeaders(connection.getHeaders());
        get.addHeader("Accept", "text/event-stream");

        connection.prepareRequest(get);

        log("Execute the request", LogLevel.Verbose);
        mConnectionFuture = mHttpConnection.execute(get, new ResponseCallback() {

            @Override
            public void onResponse(Response response) {
                try {
                    log("Response received", LogLevel.Verbose);
                    throwOnInvalidStatusCode(response);

                    mConnectionFuture.setResult(null);

                    StringBuilder buffer = new StringBuilder();
                    String line = null;

                    log("Read the response content by line", LogLevel.Verbose);
                    while ((line = response.readLine()) != null) {
                        buffer.append(line);
                        buffer.append("\n");
                        String currentData = buffer.toString();
                        if (currentData.endsWith(END_OF_SSE_MESSAGE)) {
                            currentData = currentData.trim();
                            log("Found new data: " + currentData, LogLevel.Verbose);
                            if (currentData.equals(DATA_INITIALIZED)) {
                                log("Initialization message found", LogLevel.Verbose);
                            } else {
                                String content = currentData.substring(SSE_DATA_PREFIX_LENGTH).trim();

                                log("Trigger onData: " + content, LogLevel.Verbose);
                                callback.onData(content);
                            }

                            buffer = new StringBuilder();
                        }
                    }

                    // if the request finishes, it means the connection was finalized
                } catch (Throwable e) {
                    if (!mConnectionFuture.isCancelled()) {
                        mConnectionFuture.triggerError(e);
                    }
                }
            }
        });

        return mConnectionFuture;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy