Wednesday Feb 27, 2013

Tyrus 1.0-b12 released

This release implements new version of WebSocket API which introduces major renames and even some changes in the way how you can configure advanced behavior. Unfortunately, this will make all related applications written using Tyrus uncompilable and already compiled ones undeployable (when integrated to Glassfish).

I'm sure we will receive lots of bugs relates to this change, but all I can do is try to prevent is somehow - for example by writing list of changes which you are reading right now :).

Important renames

Original name Current name
@WebSocketEndpoint @ServerEndpoint
@WebSocketClient @ClientEndpoint
@WebSocketOpen @OnOpen
@WebSocketMessage @OnMessage
@WebSocketPathParam @PathParam
@WebSocketClose @OnClose
@WebSocketError @OnError

There were no changes in packaging, so javax.websocket or javax.websocket.server is still valid.

Other changes

Another set of changes is related to Endpoint configuration. ServerEndpointConfiguration and ClientEndpointConfiguration is still there, but default implementations are gone (package private); users are supposed to use ServerEndpointConfiguraiontBuilder and ClientEndpointConfigurationBuilder in order to create new configuration instance. This change is not yet complete, so prepare for another renaming (Configuration will be Config).

Last but not least is separating user implementation from Configuration to Configurator. There are two of them, Server and Client side and they take care of calls like "matchURI", "modifyHandshake", "beforeRequest", "afterResponse". Usually you don't really need to call them, so API/RI providers default implemetation, but you might find these useful in some advanced cases, like implementing your own totally cool and unheard path matching algorithm. This class will also be renamed in next release (to something like ServerEndpointConfig.Configurator), but functionality should stay very similar (if not exactly the same).

Additionall, @ServerEndpoint and @ClientEndpoint now do NOT have configuration parameter. Everything from EndpointConfiguration should be configurable as annotation parameters plus you can set Configurator here for some more advanced usecases.

Deployment has been also altered. ServerApplicationConfiguration now deploys annotated classes or ServerEndpointConfiguration INSTANCES. Newly introduced method "getEndpointConfigurations" takes set of scanned Endpoint descendants and its up to implementor which of them will be included in returned set. Endpoint descendant needs some more info about the deployment (path, encoders, decoders, ...), so ServerEndpointConfiguration has to be created. Please note that any "loadable" endpoint can be returned (scanned classes may be ignored).

Session interface also received some refactorings, "getRemote()" dissapeared and was replaced by "getBasicRemote()" and "getAsyncRemote()". You can guess what can you do with them. On a related note - RemoteEndpoint is no longer usable on its own, it just provides common base for RemoteEndpoint.Basic and RemoteEndpoint.Async. Methods related to sending messages were also renamed, sendString is now sendTest, sendBytes is now sendBinary and these names are used for partial messages as well (only difference is now different parameters).

Let's get to the code part:

Plain echo endpoint:

@ServerEndpoint("/plainEcho")
public class PlainEcho {

    @OnMessage
    public String onMessage(String s) {
        return s;
    }
}

ServerEndpointConfigugurator:

    @ServerEndpoint(value = "/echo", configurator = MyServerConfigurator.class)
    public static class TestEndpoint {

        @OnMessage
        public String onMessage(String message) {
            return message;
        }
    }

    public static class MyServerConfigurator extends ServerEndpointConfigurator {

        @Override
        public void modifyHandshake(ServerEndpointConfiguration sec,
                                    HandshakeRequest request,
                                    HandshakeResponse response) {
            final List<String> list = request.getHeaders().get(HEADER_NAME);
            response.getHeaders().put(HEADER_NAME, list);
        }
    }

ServerApplicationConfiguration programmatic deployment:

    public static class MyAppConfig implements ServerApplicationConfiguration {

        @Override
        public Set<ServerEndpointConfiguration> getEndpointConfigurations(Set<Class<? extends Endpoint>> endpointClasses) {
            return new HashSet<ServerEndpointConfiguration>() {{
                add(ServerEndpointConfigurationBuilder.create(MyEndpoint.class, "/myEndpoint").build());
            }};

        }

        @Override
        public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
            return null;
        }
    }

Session:

    @OnOpen
    public void onOpen(Session session) throws IOException {
        session.getBasicRemote().sendText("onOpen");
        session.getBasicRemote().sendBinary(byteBuffer);
        final Future<Void> future = session.getAsyncRemote().sendText("myText");
    }

I'm sure I did not covered all changes (things are still moving forward); best source for info about API is javadoc and spec document: http://java.net/projects/websocket-spec/downloads/directory/Spec%20javadoc%20Drafts/v013 . And as always, you can always ask us! Tyrus (implementation): users@tyrus.java.net ; API: users@websocket-spec.java.net.

About

Pavel Bucek

Search

Categories
Archives
« February 2013 »
SunMonTueWedThuFriSat
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
28
  
       
Today