Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-11 without WebSocket isn't stupid simple enough #1319

Open
alopatindev opened this issue Jun 19, 2024 · 7 comments
Open

NIP-11 without WebSocket isn't stupid simple enough #1319

alopatindev opened this issue Jun 19, 2024 · 7 comments

Comments

@alopatindev
Copy link
Contributor

alopatindev commented Jun 19, 2024

Before publishing some events from browser client I'd like to check whether certain features are available on the relays (to save some bandwidth by not spamming servers with useless requests).

When NIP-11 isn't implemented I want to assume that all capabilities are available for such relays.

Ideally I'd like to fetch relays capabilities on relays pool initialization step, without creating extra connections. Can any browser client library do that right now?

Properly doing the https GET to fetch the JSON and then upgrading to WebSocket doesn't look simple to me.

Also it requires correct server CORS configuration (currently it's not always the case).

Could we have (instead or additionally) a WebSocket request for the same JSON document?

@fiatjaf
Copy link
Member

fiatjaf commented Jun 19, 2024

I'm used to people coming here asking us to replace the WebSocket for a bunch of HTTP APIs. This is the first time I've seen someone asking for the opposite.

I sympathize with you, you're probably right that using a WebSocket would have been better, but I think the hurdle and the damage that would be caused by trying to push this change would be much bigger than the benefits we would gain from it.

@staab
Copy link
Member

staab commented Jun 20, 2024

Why is that? This seems like a nice idea to me, if nothing came back you could fall back to http or go without.

@alopatindev
Copy link
Contributor Author

alopatindev commented Jun 20, 2024

I forgot to mention another scenario: I'd like to ignore some relays for reading before I subscribed to messages from them (because language_tags turned out to be irrelevant on this part of multilingual website).

For now due to some CORS issue client is damned to violate rules of some relays: client will still connect to such relay without knowing it doesn't support this language. Client might receive, react to or even publish their own messages in irrelevant language on this relay.

And at the same time the same misconfigured relay might be useful to this client, on a different page of the same (multilingual) website even. Until user will ironically receive ban for violating the rules.

If it's not CORS issue than it's (inevitable? or just hard to solve properly?) performance drop for this client:

  • either due to waiting for JSON and only then reopening a connection for new messages
  • or because of connecting to too many irrelevant relays first, receiving messages from them and possibly receiving JSON concurrently using other connections
    • this is even worse, because now we'll either
      • need to wait until JSON is (not) received and only then we can show messages
      • or we'd need to show messages and then suddenly hide/remove some of the messages (this will appear buggy to user and complicate client logic).

If adding a new (additional) WebSocket request makes protocol too complicated and removing HTTPS version will cause too much damage, another approach would be just make a new NIP that provides the WebSocket interface for NIP-11's JSON.

This will make it possible to leave both implementations or choose which one one wants to implement or maybe potentially deprecate entire NIP-11 later if it will receive too little interest in proper implementation (and server configuration).

@dskvr
Copy link
Contributor

dskvr commented Jun 26, 2024

@alopatindev Many NIP-11 details are included in NIP-66 events for discovery and meta events, as well as sometimes the entire NIP-11 as stringified JSON in the event content

Sidenote: One hurdle to transposing NIP-11 as-is to events tags, is that the JSON scheme for NIP-11 does not transpose well to tags due to it's depth and an array of objects for fees

@alopatindev
Copy link
Contributor Author

alopatindev commented Jul 7, 2024

I'm used to people coming here asking us to replace the WebSocket for a bunch of HTTP APIs

@fiatjaf interesting, you mean a bunch of HTTP requests without bidirectional streaming at all?

I actually think that HTTP/2 in particular would be a better choice than WebSocket today for entire Nostr protocol, specifically because

  • it defines multiplexing
  • supports bidirectional streaming without all this upgrade-to-WebSocket-complications
  • perhaps flow control requirement is useful as well.

Maybe we should do the opposite? How about gradually migrating everything to specifically HTTP/2 (and then probably to HTTP/3 with a fallback to HTTP/2 for older clients) starting with

  • recommending NIP-11 (and whatever that mentions connection over HTTP to relays) to be implemented specifically with HTTP/2
  • and later adding HTTP/2-based bidirectional communication and deprecating < HTTP/2 + WebSocket?
    • I guess it's easier to migrate to something like this from WebSocket, rather than to a bunch of new HTTP requests.

Also, even though HTTP/3 is still unreleased and requires manual enabling in browser, it looks like it's already possible to use it.

HTTP/3 is based on UDP/QUIC which gives improved congestion control than in TCP (however requires doing things in user space rather than in kernel space like TCP used to, very different protocol).

Is that right that the lack of proper congestion control is the reason why we currently publish messages sequentially (even though I personally find it annoyingly slow) rather than concurrently?

@mikedilger
Copy link
Contributor

First off, if we are going to make a breaking change to nostr such as moving to HTTP/2, then we should make a bunch of other breaking changes at the same time in order to fix longstanding problems, such as binary events, subkey handling, etc. And we could incorporate NIP-11 data into the main protocol too (the point of this issue).

But I'm not at all convinced that HTTP/2 is a good idea even having read that entire linked stackoverflow discussion. That top answer is a weird and hacky way to use HTTP/2 which would probably encounter many implementation edge cases of breakage because HTTP/2 is still fundamentally a request-response model.

Also, multiplexing doesn't improve performance. The data is still serialized through packets. It just handles framing and reassembly to "organize" your data for you. It will still be just as "annoyingly slow" if it was changed.

Lastly, the performance gained by avoiding head-of-line-blocking is primarily a means of latency reduction, with no effect on bandwith. Latency issues aren't very signficant for nostr. They are for voice communication, for real-time gaming, for video streaming. But for nostr it's not really a big deal. Not motivating enough.

@bezysoftware
Copy link
Contributor

FYI #1434

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants