How is it different from SignalR you ask? Well internally it's built on the same underlying tech but the big difference is that there's no client requirement or protocol requirement, BYOWL (bring your own websocket library).
The mainline scenarios are also focused on severless so we can handle your long running websocket connections and trigger HTTP calls to any backend. It can be azure functions or any addressable HTTP endpoint!
And no, Azure SignalR isn't dead, it's alive and kicking for all of your #signalr needs :).
Unlike SignalR, Azure Web Pubsub is just websockets, there's no long polling or server sent events fallback nor automatic reconnect, it's just you an your websocket client.
This lowers the barrier of entry for using the service, you just need an HTTP client and a websocket client to get going.
And lastly, if you're using Azure SignalR continue to do so unless there's something limiting you from using it in more places. This service won't benefit you if that's not the case.
Here are some reasons to stick with Azure SignalR:
- Your primarily a .NET shop
- If you need fallback transports other than WebSockets (Long polling, Server sent events).
- The existing SignalR client platforms work for you (including 3rd party swift and python clients).
- You need more complex invocation patterns and you don't want to manage a custom protocol. SignalR supports RPC, Streaming etc.
- Handling connectivity/keep alive/pings. The SignalR protocol makes sure that connections stay alive by sending pings back and forth.
- If you need a low latency end to end connection between your application code and the service. Azure Web pubsub currently only supports serverless backends (HTTP based), this wouldn't be as great for things like gaming (though I know we're not all writing games).
- If you don't want to manage the reconnect logic yourself.
Azure Web Pubsub gets you more reach (raw websockets) at the cost of putting more of the logic in your hands. This works well if you have simple application messaging patterns.
• • •
Missing some Tweet in this thread? You can try to
force a refresh
After spending the last 5 years deep in networking code, I can say one of the most fundamental missing pieces is the ability to know why a connection closed (root causing the problem).
I wish all the protocols from here on out would also have a "reason for close" field for additional debugging information. The cumulative time that has been lost trying to debug what part of the stack caused the connection to drop (OS, proxy, libraries) probably adds up to years.
This gets even more complicated by these "invisible layers" introduced by virtualization. Cloud networking comes to mind... don't forget the layers built on top of that in orchestrators like kubernetes.
The transition to asynchronous code changes a lot of the basics we're used to. There's usually much more concurrency in these systems and that becomes more challenging to diagnose when things go wrong. #dotnet#aspnetcore
The threads are usually switching between lots of concurrent operations as various IO operations complete. Here's an example of visualizing lots of concurrent operations happening in the parallel tasks window. The right is parallel stacks. Async stacks vs OS thread stacks.
Essentially the async logical stacks are linked lists of objects stored on the heap. There may not be any code executing if a request is waiting on IO for example.
4 months I got to spend time with friends and family. We went on cruises, and had lots of beach days. The kids learned how to swim at the beach. They got to live with grandparents for 3 of those 4 months. Got to spend my birthday here for the first time in over 10 years.
Got to experience what it would be like to work remotely from Barbados. Started a relationship between Microsoft and the UWI (University of the West Indies). Joined a WhatsApp group of coders of Barbados and am doing what I can to make them love .NET 🤣.
.NET APIs you didn't know existed. StringBuilder.GetChunks docs.microsoft.com/en-us/dotnet/a…. You can use this API to get access to the internal buffer of the StringBuilder instead of turning it into a String. #dotnet
StringSplitOptions.TrimEntries docs.microsoft.com/en-us/dotnet/a…. Ever split a string and didn't want to trim each entry? Me too, now you can use this enum to do it!
There are some common issues I see when people use ConcurrentDictionary:
- Dealing with the fact that GetOrAdd executes the creation callback more than once. This means if you create something expensive, it'll happen more than once. (this is documented) #dotnet
- If you create a disposable object in your factory and it gets called multiple times, the created objects will never be disposed.
- Making sure asynchronous factories and are called once. (making all callers wait on the same value).
Here's a contrived example of the resource leak. The code runs a couple of concurrent operations and uses GetOrAdd to cache a FileStream. This will call File.OpenRead potentially multiple times which will result in opening a handle to the resource and not disposing it.
Week 2 of analyzing how goroutines pause and resume and how the networking stack and other subsystems interact with the primitives exposed by the runtime.
One of the things I appreciate about C# is how many low level features are directly exposed to users. #golang#dotnet
In golang, it's not possible for you to implement pausing and resuming of goroutines other than by using the primitives go offers, channels, network IO, timers (sleep). This is fine for most applications but comes with additional overhead.
I also learned that go's GC doesn't move pointers and therefore there's no way to pin memory when working with C interop. There's no equivalent to passing around a GCHandle in go, just don't pass things with managed pointers to C.