+1 to Joe's response. URL parameters matter only at connection time and
that's when that kind of thing should be exposed. The rest is just passing
bytes back and forth.
On Sat, Sep 15, 2012 at 5:27 PM, Joe Walnes <joe_at_walnes.com> wrote:
> I echo most of Mark's opinions, with one difference...
>
> I'd give a +1 to suggestion 3. I've seen this pattern used frequently.
> e.g. /stream/newsfeed/{category}.
>
> However, I would pass the path parameters to the @WebSocketOpen call as
> it's the kind of thing you care about at connection time, rather than each
> individual message.
>
> On Sat, Sep 15, 2012 at 10:52 AM, Mark Thomas <mark_at_homeinbox.net> wrote:
>
>> On 15/09/2012 00:43, Danny Coward wrote:
>> > Hi folks,
>> >
>> > Wanted to get your input on a few ideas to do with more flexible path
>> > matching. Currently in the API, the endpoint by default gets matched on
>> > the URI for an opening handshake using an exact match with the URI used
>> > to register it. And the developer can override this behavior with
>> > whatever matching criteria they want to.
>> >
>> > But for the developer using annotations, I wanted to explore the options
>> > for something more flexible than just exact match on the path()
>> > attribute of the class-level @WebSocketEndpoint annotation. It would
>> > allow POJOs to map more flexibly in the URL space, could be useful for
>> > developers (especially to javascript clients).
>> >
>> > Here are a few directions to look at (some inspired by servlet and
>> > JAX-RS schemes):-
>> >
>> > 0) Re-use the servlet concept of url-patterns
>> >
>> > In this case, the path() attribute on the @WebSocketEndpoint annotations
>> > would be able to contain servlet url-patters, matching defined as in the
>> > servlet spec, for example:-
>> >
>> > @WebSocketEndpoint(path="/club") - endpoint matches /club only
>> > @WebSocketEndpoint(path="/club/*") - endpoint matches anything beginning
>> > /club
>> > @WebSocketEndpoint(path="/club/*.websocket") - endpoint matches anything
>> > ending .websocket
>> I hope you mean path="*.websocket" here.
>>
>> +1 otherwise
>>
>> > 1) Allow method level annotations to define subpaths.
>> >
>> > Here, the class level @WebSocketEndpoint defines a path, as it does now.
>> > But, for example @WebSocketMessage could add a subpath in order to match
>> > only on the aggregate path. For example,
>> >
>> > @WebSocketEndpoint(path="/club")
>> > public class Bar {
>> >
>> > @WebSocketMessage(subpath="/normal-people")
>> > public void takeOrder(String orderString, Session session) {
>> > // called from websocket clients who connected to
>> > /club/normal-people
>> > // yeah, we'll get to you when we get to you
>> > }
>> >
>> > @WebSocketMessage(subpath="/vips")
>> > public void takeExpressOrder(String orderString, Session session) {
>> > // called from websocket clients who connected to /club/vips
>> > // ice and lemon ?
>> > }
>> > }
>>
>> -0
>>
>> I can see what you are getting at but I'd prefer to see two classes
>> (with a common base class) mapped to the separate end points.
>>
>> In the case above:
>> - Where do messages for the "/club" endpoint get routed?
>> - Is it even valid to connect to the "/club" endpoint?
>> - What if users don't went "/club" to be a valid endpoint?
>>
>> This option appears to adds a lot of potential complexity and corner
>> cases. These all need to be carefully thought through and the required
>> behaviour clearly specified. On a first look I'm not convinced that work
>> is work the effort (although I'm prepared to be convinced otherwise).
>>
>> > 2) Allow regular expressions in the URI paths
>>
>> -1
>>
>> This is a bad idea. It creates a mapping ambiguity when multiple regular
>> expressions match a request. I am strongly against this.
>>
>> > 3) Allow a kind of path templating, where path segments may be used in
>> > web socket code.
>> >
>> > Here, the kind of URIs allowed in the @WebSocketEndpoint path()
>> > attribute could include variable path segments, where the variables can
>> > be passed as parameters (annotated with a new @PathParam annotation)
>> > into the methods on the POJO later.
>> >
>> > @WebSocketEndpoint(path="/club/{member-level}/{member-name}")
>> > // means this POJO is an endpoint for all URLs that begin with "/club"
>> > public class Bar {
>> > @WebSocketMessage
>> > public void takeOrder(String orderString,
>> > @PathParam(id="member-level") String mLevel,
>> > @PathParam(id="member-name") String mName, Session session) {
>> > if ("vip".equals(mLevel)) {
>> > // "Good evening, " + nName + " I have your drink already
>> > prepared."
>> > } else {
>> > // wait your turn mate
>> > }
>> > }
>> > }
>>
>> +0
>>
>> I could easily be convinced to be +1 if there was a user demand for
>> this. I haven't seen it yet but it is still early days for the WebSocket
>> users in Tomcat.
>>
>> > I think in general one, or some hybrid of two of these four approaches
>> > would be a good addition to the model. The servlet one (0) may be well
>> > understood, but doesn't seem as useful as 2) or 3). Clearly all four
>> > would be overkill.
>> >
>> > I'd be interested to know your thoughts on these approaches.
>>
>> In summary:
>> 0) Yes
>> 1) Maybe, but it looks like a lot of work
>> 2) No way
>> 3) Yes, if there is a demand for it
>>
>> Mark
>>
>>
>
--
You can find me on the net at:
http://antwerkz.com http://antwerkz.com/+
http://antwerkz.com/twitter http://antwerkz.com/github