Coder Social home page Coder Social logo

websockets about pushpin HOT 8 CLOSED

fastly avatar fastly commented on May 17, 2024
websockets

from pushpin.

Comments (8)

jkarneges avatar jkarneges commented on May 17, 2024

Concrete definition for basic functionality:

Proxy includes the "grip" extension in the Sec-WebSocket-Extensions header. Proxy will also include the Grip-Sig header:

GET /websocket/path/ HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Grip-Sig: [... JWT ...]
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ=
Sec-WebSocket-Extensions: grip
...

Server includes the "grip" extension in its response in order to indicate support. If the server does not include the grip extension in its response, then the proxy will assume that the server is unable to send grip control messages. For now, this would mean that the session becomes a passthrough with no grip capabilities at all.

If the server accepts the grip extension, then it is able to send normal messages to be relayed as-is to the client, or control messages to be processed by the proxy. The server denotes the kind of message by including a prefix in the payload of the message. If the message spans multiple frames, then the prefix would only be included in the first frame. By default, the prefix for normal messages is "m:" and the prefix for control messages is "c:". The proxy will strip off the prefix before relaying or processing.

The "grip" extension shall have an optional parameter called "message-prefix" that the server can use to override what the prefix should be for normal messages. The server can even specify a blank string for this value, to indicate that there should be no prefix at all. This can be useful if the server speaks entirely in JSON, in which case there is no chance of conflict with control messages (a JSON payload would never begin with "c:"). For example:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Extensions: grip; message-prefix=""
...

Control messages would use JSON format, encoded as an object with field "type" indicating the type of control message. All other fields in the object would be parameters for the message. The following control messages would be defined:

  • { "type": "subscribe", "channel": "{channel}" }
  • { "type": "unsubscribe", "channel": "{channel}" }
  • { "type": "detach" }

To be clear, these are messages that the server sends to the proxy. The client/browser has no awareness of GRIP. The server would use the subscribe and unsubscribe messages to control the GRIP channels that the client's WebSocket connection is subscribed to. The detach message would be used to disconnect from the proxy without the proxy disconnecting from the client. Any further messages received by the client would be dropped by the proxy. Detached mode only makes sense if the connection has been subscribed to one or more channels and there is no expectation for the client to send anything further. This may be useful if the connection is used only for one-way transmission.

The server may publish data to the proxy via EPCP using the "ws-message" format. This format contains just one child field, "content" or "content-bin", containing an entire message to be relayed to all clients subscribed to the channel being published to. The "content" field is a string containing a text message. The "content-bin" field is a string containing a binary message encoded in Base64.

This proposal does not address connection sharing or multiplexing. We can look into these things later on.

from pushpin.

jkarneges avatar jkarneges commented on May 17, 2024

A key feature of a GRIP proxy in the context of HTTP is its ability to handle long-lived connection management. However, it's less clear how a proxy would take over this responsibility in the context of WebSockets. Detaching is not a complete solution since many WebSocket protocols are bidirectional.

Some ideas:

  • The WebSocket application server itself could abstract away the notion of connections from the message handlers. It could send no open/close events to handlers, and instead send only message events that are each tagged with necessary metadata. The metadata could be auth information determined during the initial handshake. This would be enough to implement semi-stateless RPC, while using GRIP for pubsub.
  • The proxy could speak some kind of alternative protocol to the origin server, where metadata is tagged onto each message. For example, a WebSocket could be used as the transport, but nothing interesting would be transferred in the handshake, and closing the connection would have no meaning. Instead, each message sent over the connection would contain all the necessary information for the origin server to formulate tagged responses. This would work nicely with multiplexing messages to/from many clients over one connection between proxy and origin.
  • Gateway to HTTP. If we're sending the full state with every message and connections have no meaning, then we're pretty much back in HTTP territory.

from pushpin.

CMCDragonkai avatar CMCDragonkai commented on May 17, 2024

This would be really cool. It's like we're adapting request/reply frameworks such as the majority of PHP to be able to do all sorts of real time things.

On the otherhand, doing any kind of complicated realtime logic may still be more simple to do in evented or long running daemons.

from pushpin.

jkarneges avatar jkarneges commented on May 17, 2024

Pushpin's philosophy is that most realtime applications only need request/response and publish/subscribe messaging patterns to get the job done. This makes the backend server much easier to manage. All it needs to do is respond to requests or perform fire-and-forget publishes, both of which can be done statelessly. Many realtime server applications are connection/session oriented, but this is often overkill and harder to debug.

You're right, though, there are some apps that do need this extra state. These are mainly ones that don't map very well to publish/subscribe, such as when pushed data is heavily tailored to the receiving client's session.

from pushpin.

CMCDragonkai avatar CMCDragonkai commented on May 17, 2024

Cool. At any case, will be watching for when websockets are added!

from pushpin.

jkarneges avatar jkarneges commented on May 17, 2024

The functionality described by the second comment in this thread is actually added already. It requires a WebSocket origin server though.

from pushpin.

jkarneges avatar jkarneges commented on May 17, 2024

Support for HTTP origin servers is on the way, using this approach:
https://github.com/fanout/pushpin/blob/master/doc/websocket-over-http.md

from pushpin.

jkarneges avatar jkarneges commented on May 17, 2024

WebSocket-to-HTTP gatewaying is now possible!

I'm not going to bother with multiplexing WebSockets over WebSockets yet. WebSocket-to-HTTP gatewaying should be good enough for most people. If anyone ever wants WebSocket multiplexing in the future, we can create a new ticket.

from pushpin.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.