Comments (8)
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.
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.
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.
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.
Cool. At any case, will be watching for when websockets are added!
from pushpin.
The functionality described by the second comment in this thread is actually added already. It requires a WebSocket origin server though.
from pushpin.
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.
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)
- Websocket-over-HTTP content-type charset HOT 2
- unable to install pushpin via Dockerfile [dl.bintray.com is forbidden] HOT 1
- intergate a small backend server with existing pushpin Docker file HOT 3
- Schema of the architecture of pushpin ? HOT 1
- Error 502 when proxy forwarding from nginx HOT 1
- Multi-arch docker image with M1 support HOT 3
- Pushpin installation from JFrog's DEB repo times out HOT 1
- Not able to publish messages via 0MQ from backend server HOT 4
- Memory increasing when clients connect but doesn't free up when they disconnect HOT 5
- 1% of traffic receives 502
- How to log connection Id while making a http call to Backend service? HOT 1
- tp://localhost:5561/publish/ by default
- Support qt6 HOT 1
- issue while installing pushpin on rhel-8, any additional repository has to configure ? HOT 1
- Pushpin
- Fast
- Third party Pushpin hosts? HOT 1
- HTTP Custom
- Memory leak after upgrade to 1.38.0 HOT 5
- Proxy not reusing sessions for first batch of recover requests HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pushpin.