MostAwesomeDude / txWS

Twisted WebSockets
Other
94 stars 29 forks source link

self.transport.location not available from wrapped connectionMade #14

Open n1ywb opened 11 years ago

n1ywb commented 11 years ago

It seems that within the context of the wrapped connectionMade method, the contents of self.transport.location are not yet set to the correct value, but rather the default '/'.

It would be nice if the call to the wrapped connectionMade method were made after the websockets connection was fully negotiated.

n1ywb commented 11 years ago

Here's one way to hack around it by monkey patching validateHeaders to make a callback.

This is helpful in a RESTful streaming API where there's really no need for the client to send anything to the server. Once the server knows the path it can determine the appropriate resource and begin streaming it.

class MyProtocol(Protocol):
    def connectionMade(self):
        # monkey patch txws to notify us after it parses the location field
        oldValidateHeaders = self.transport.validateHeaders
        def wrap(*args, **kwargs):
            r = oldValidateHeaders(*args, **kwargs)
            if r: self.headersValidated()
            return r
        self.transport.validateHeaders = wrap

    def headersValidated(self):
        log.msg("Websocket headers validated, loc: %r" %
                self.transport.location)
MostAwesomeDude commented 11 years ago

Sorry, but location isn't a standard attribute of ITransport. Why do you want this? You really should be creating separate Resources and passing in the expected location at creation time, rather than looking up possibly-nonexistent attributes.

n1ywb commented 11 years ago

When a websocket connection is made, the client sends the URI it is requesting, and somewhere in the server some code has to look at that URI and branch based on it, e.g. to route the request to the appropriate Resource. Is that code already in txWS and I just missed it? If not, how would you suggest implementing that?

MostAwesomeDude commented 11 years ago

Urgh, no, it's in Twisted #4173 (http://tm.tl/4173/) but not in txWS. Not sure how to do that here, since txWS is emphatically not HTTP.

o3bvv commented 11 years ago

I think, I've implemented something like n1ywb suggests: https://github.com/oblalex/txWS/blob/f495c1ce4906db80c2b18f77e942a37d28ad40a9/echo.py

caveats:

  1. Unfortunately, WebSocketProtocol and WebSocketFactory were changed a bit: they are not wrapping now. I cannot suppose now how to combine wrapping and resourced approached.
  2. I changed txws.py and echo.py only. So, tests will fail.
  3. I am not a Twisted guru
  4. There is lots of place for refactoring and errors handling in current implementation.

Nevertheless, the example shows a way the task can be done. It's lighter to finish this approach, instead of using autobahn's WAMP or something like that.