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

hprose.server.HproseWebSocketService Maven / Gradle / Ivy

Go to download

Hprose is a High Performance Remote Object Service Engine. It is a modern, lightweight, cross-language, cross-platform, object-oriented, high performance, remote dynamic communication middleware. It is not only easy to use, but powerful. You just need a little time to learn, then you can use it to easily construct cross language cross platform distributed application system. Hprose supports many programming languages, for example: * AAuto Quicker * ActionScript * ASP * C++ * Dart * Delphi/Free Pascal * dotNET(C#, Visual Basic...) * Golang * Java * JavaScript * Node.js * Objective-C * Perl * PHP * Python * Ruby * ... Through Hprose, You can conveniently and efficiently intercommunicate between those programming languages. This project is the implementation of Hprose for Java.

There is a newer version: 2.0.38
Show newest version
/**********************************************************\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: http://www.hprose.com/                 |
|                   http://www.hprose.org/                 |
|                                                          |
\**********************************************************/
/**********************************************************\
 *                                                        *
 * HproseWebSocketService.java                            *
 *                                                        *
 * hprose websocket service class for Java.               *
 *                                                        *
 * LastModified: May 3, 2016                              *
 * Author: Ma Bingyao                   *
 *                                                        *
\**********************************************************/
package hprose.server;

import hprose.common.HproseContext;
import hprose.common.HproseMethods;
import hprose.io.ByteBufferStream;
import hprose.util.concurrent.Action;
import hprose.util.concurrent.Promise;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import javax.websocket.EndpointConfig;
import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;

public class HproseWebSocketService extends HproseService {
    private final static ThreadLocal currentContext = new ThreadLocal();
    private EndpointConfig config = null;

    public static WebSocketContext getCurrentContext() {
        return currentContext.get();
    }

    @Override
    public HproseMethods getGlobalMethods() {
        if (globalMethods == null) {
            globalMethods = new HproseWebSocketMethods();
        }
        return globalMethods;
    }

    @Override
    public void setGlobalMethods(HproseMethods methods) {
        if (methods instanceof HproseWebSocketMethods) {
            this.globalMethods = methods;
        }
        else {
            throw new ClassCastException("methods must be a HproseWebSocketMethods instance");
        }
    }

    @Override
    protected Object[] fixArguments(Type[] argumentTypes, Object[] arguments, ServiceContext context) {
        int count = arguments.length;
        WebSocketContext wsContext = (WebSocketContext)context;
        if (argumentTypes.length != count) {
            Object[] args = new Object[argumentTypes.length];
            System.arraycopy(arguments, 0, args, 0, count);
            Class argType = (Class) argumentTypes[count];
            if (argType.equals(HproseContext.class) || argType.equals(ServiceContext.class)) {
                args[count] = context;
            }
            else if (argType.equals(WebSocketContext.class)) {
                args[count] = wsContext;
            }
            else if (argType.equals(EndpointConfig.class)) {
                args[count] = wsContext.getConfig();
            }
            else if (argType.equals(Session.class)) {
                args[count] = wsContext.getSession();
            }
            return args;
        }
        return arguments;
    }

    public void setConfig(EndpointConfig config) {
        this.config = config;
    }

    @SuppressWarnings("unchecked")
    public void handle(ByteBuffer buf, Session session) throws Throwable {
        WebSocketContext context = new WebSocketContext(this, session, config);
        int id;
        Object response = null;
        try {
            currentContext.set(context);
            id = buf.getInt();
            response = handle(buf.slice(), context);
        }
        catch (Throwable e) {
            currentContext.remove();
            return;
        }
        finally {
            ByteBufferStream.free(buf);
        }
        buf = ByteBuffer.allocate(4);
        buf.putInt(id);
        buf.flip();
        final RemoteEndpoint.Basic remote = session.getBasicRemote();
        remote.sendBinary(buf, false);
        if (response instanceof Promise) {
            ((Promise)response).then(new Action() {
                public void call(ByteBuffer value) throws Throwable {
                    try {
                        remote.sendBinary(value, true);
                    }
                    finally {
                        ByteBufferStream.free(value);
                    }
                }
            }).complete(new Action() {
                public void call(Object o) throws Throwable {
                    currentContext.remove();
                }
            });
        }
        else {
            try {
                remote.sendBinary((ByteBuffer)response, true);
            }
            finally {
                ByteBufferStream.free((ByteBuffer)response);
                currentContext.remove();
            }
        }
    }

    public void handleError(Session session, Throwable error) {
        WebSocketContext context = new WebSocketContext(this, session, config);
        fireErrorEvent(error, context);
    }
}