Spreads / SignalW

Even simpler and faster real-time web for ASP.NET Core.
Other
127 stars 13 forks source link

Add Tags #4

Open VladimirAkopyan opened 6 years ago

VladimirAkopyan commented 6 years ago

When I search C# websocket server this does not come up. You would get many more stars and users if you add appropriate tags.

buybackoff commented 6 years ago

I got c.85 or more stars from David Fowler tweet, and only the rest c.6 are organic. So a blog post (leading to an influencer tweet) or just such a tweet are much more effective. I added some tags, which ones are missing? And what text description do you propose?

VladimirAkopyan commented 6 years ago

That more dramatic than I expected. I'd suggest 'Server', 'rpc', asp and maybe dotnetCore I think the description is fine. About a month ago you did explain how you did a ton of optimisation work, and that's probably worth mentioning. Github search seems really odd, when I search with websocket (singular) the project doesn't come up, but when I search websockets it does. I hope that's because it's still indexing, otherwise it's just idiotic.

buybackoff commented 6 years ago

I wonder why you want more publicity for the library? Do you already use it in production?

I will never be able to convince the wide audience that this is a better library than SignalR; and it is probably not except for the narrow cases of small messages optimized for custom binary serialization without allocations (+ no custom protocol, just WS). I will also need to review the connection manager logic and sync it to SignalR (there were some edge cases on reliability after connection drop, I made some changes at least to keep live clients work properly and that was it) and make a lot of tests (reliability on disconnects, performance vs SignalR, profiling on large payloads with many groups/clients) - only after that I could pretend that it is ready for prime time and faster than SignalR when performance is important.

It could also happen that SignalR will be optimized for binary messages so that using a buffer pool + Spreads.Core's RecyclableMemoryStream over it will have near the same performance as SignalW over WAN. So at least I need to wait for SignalR v.1 and re-validate my initial assumptions and earlier critic of the initial version of it.

VladimirAkopyan commented 6 years ago

I am considering using it. Would you recommend SignaIR? They've implemented some protocol on top again, didn't they?
Besides SignalIR I was also looking at WampSharp - do you have any thoughts on it? I am aiming to have a "standard" protocol that's available in several programming languages as a server - that could be raw websocket, or something else.

buybackoff commented 6 years ago

I have looked into TypeScript client code and they now support MsgPack over plain binary Websockets. Maybe they have pure binary in C# now, will look in C# closer later. If I could read a binary buffer using pooled buffers, then probably MsgPack envelope is not slow compared to network. Also they have low-level Sockets stuff that could probably allow for a custom protocol. And they have Redis scale-out built-in.

Maintaining a fork is always a pain, when I did SignalW they had half-broken JSON. It was also fun to learn internals. I am afraid that they have 141 open issues, 500+ closed and are still in alpha, but probably it is a good thing - they will make it right at some point.

Do not remember details, but Wamp protocol looked even more opinionated and I ruled it out for some reason. It looked to heavy, or its available C# implementations looked so.

buybackoff commented 6 years ago

@VladimirAkopyan thinking about to use SIgnalW in production even though SignalR is almost ready. They abstract all http connections, add many not really useful features and I cannot build it locally because they target .NET Core 2.2. Just too many abstractions and difficulty to control internals. Will just learn best practices from them if they added anything. Even if performance is on par or greater in SignalR, it doesn't matter so much on WAN. In SIgnalW I will eliminate most allocations anyway and will profile regularly to have minimum overheads for small binary messages.

In the end, sending a message to N websockets connections is not that difficult, I have already implemented an analogue to SignalW in Node.js and it just works.

VladimirAkopyan commented 6 years ago

hello @buybackoff I was a bit surprised by your comment as well when you said that developing your own messaging is fraught with peril. I have been working with MQTT, and I think it's a better choice protocol-wise than Websockets. MQTT defines topics which can be used as metadata to identify messages and infer their datatype. In WS you always have to design some kind of "container" and infer message types in a hack-ish manner, always reinventing the wheel. That frees you to use any binary protocol you wish.

Take a look at https://github.com/chkr1011/MQTTnet This project has active community and the API is super-simple, you could probably use it for spreads. I am sure SignalW will beat it in performance out of the box, given all the work you've done. There are a couple questionable design choices, I think. such as locking the entire collection that has all the clients every time a message in sent. but the code is well written, easy to understand and the dude takes PR, I made one to address some of my discontent. Also it doesn't have any dependencies. I think you could adapt it for your purpose and still benefit form community, unit tests, etc.

buybackoff commented 6 years ago

In WS you always have to design some kind of "container" and infer message types in a hack-ish manner, always reinventing the wheel. That frees you to use any binary protocol you wish.

I have data headers in binary protocol that say exactly what is inside a message. As we discussed before somewhere here, pure binary gives a lot of flexibility. The topics and headers are probably very close.

One of my requirement is that I have text protocol as well as binary, and there is a boolean switch in WebSockets protocol. So if I have connections from a browser, I could send them pure JSON (yes, also with some wrapper that acts as a header). But I like simplicity and code reuse.

locking the entire collection that has all the clients every time a message in sent. why not ConcurrentDictionary? But maybe locking over List<> is faster, NetMQ does this with its active pipes.

VladimirAkopyan commented 6 years ago

You seem to have it all sorted then. In MQTT I would do something similar by prefixing all topics with their datatype, like json/users/{userid}/something To address browser usercase, they support MQTT-over-web-socket hosted inside ASP, so probably dealing with simular issues you are.

As for dictionaries, I was having discussion with the dev here: https://github.com/chkr1011/MQTTnet/pull/268 I was thinking of making a PR, not sure if that's the most pressing issue for now.