42

I have used SignalR to achieve real-time messaging functionality in several of my projects. It seems to work reliably and is very easy to learn to use.

The temptation, at least for me, is to abandon developing a Web API service and use SignalR for everything.

I feel like this could be achieved by thoughtful design, and if it were, it would mean far less client code would be necessary. More importantly, it would mean that there would be a single interface to services rather than a split interface, and in the worst case, that one could wire this up without thinking about when things get rendered, etc.

So, I would like to know:

  1. Is there any other reason not to use SignalR in lieu of all web services besides performance?
  2. Is SignalR's performance sufficiently concerning that it would not make sense to do so?

It has long been a dream of mine to be able to translate server-side object and service definitions to client-side service access code without something silly like node.js. For instance, if I define an interesting object InterestingObject and a service to CRUD the object InterestingObjectService, I can define a standard URL route to the service - say, "/{serviceName}/{methodName}" - but I still need to write client code to access the service. Since the object is going to be passed from client to server and back, there is no practical reason to have to define the object explicitly in client-side code, nor should there be a need to explicitly define the routes to perform CRUD operations. I feel like there should be a way to standardize all of this so that it is possible to write a client under the assumption that service access works from the client to the server and back as transparently as it would if I were writing a WinForms or Java Applet or Native App or what have you.

If SignalR is good enough to use in lieu of a traditional web service, it may be a viable way to achieve this. SignalR already includes functionality to make the hub work like service I describe, so I could define a common base (CRUD) service that would offer all of this functionality out-of-the-box with some reflection. Then I could almost take for granted the service access, saving me the annoyance of re-writing code to access something that could be accessed by convention - and more importantly, the time I would have to spend writing code to define how this is updated in the DOM.

After reading my edit I feel like it may be a little nonsensical so please feel free to ask me if you have questions about what I am getting at. Basically, I want the service access to be as transparent as possible.

  • 5
    If you have a magical network card that can hold open an infinite number of sockets and a magical network that can support an infinite amount of bandwidth and a magical server that has an infinite amount of memory and cpu cycles then websockets only is a great choice! – Jarrod Roberson Sep 7 '15 at 15:04
50

Those two technologies have a very different purpose.

  • REST is for ordinary calls to an API, with client being an active actor of the exchange. When the client needs to find GPS coordinates of an address, the client initiates the call to the API and waits until it receives the coordinates, or a error occurs, or a timeout elapses.

  • Web sockets are for everything which needs to do things the opposite way. For example, when I use an intranet website which shows me in real time the logs and the performance of different servers, the client may be passive and wait until the server sends him a newly published log message or performance metrics.

The difference is clear: in the first case, the client decides when it needs a specific piece of information; in the second case, the client simply waits to be contacted, and may not know when it would be.

In some way, both are interchangeable: you can implement web sockets when you don't need them (i.e. the client will call the server through web sockets instead of making a REST call) and you can use polling or long polling as a substitute to web sockets (given that this was used successfully for years until web sockets became so popular).

But their interchangeability comes at a cost:

  • When you use polling or long polling instead of web sockets, you're often wasting bandwidth.

  • When you use web sockets to do what can be done through web api, you keep all the connections from all the active clients opened, which may not be what you really want. For a small website where you expect to have at most 5 clients at the same time, this is not an issue. For a service such as Amazon AWS, this wouldn't be easy to solve technically.

Don't use web sockets when you don't need them. To get GPS coordinates of an address, I gain nothing in opening web sockets connection, making the call, waiting for an answer and closing the connection: REST fulfills my needs for such scenarios.

  • If you find yourself repeatedly and frequently checking for information through a REST call to a service, this may be a good sign that you should move to web sockets. Similarly, Stack Overflow reduces bandwidth usage by using web sockets, since it helps people to not spend their time pressing F5 on the home page to see if they have new messages.

  • If you find that you open web sockets connections, use them to make a single call, and then close them, or if your connections remain opened but the server is sending something to the client only on client's request, switch to REST.

Also, web sockets have still a limited support and are not always easy to implement. While SignalR makes it easy to implement, this doesn't mean that you won't have any difficulties to implement it in other languages/contexts/environments. With REST, that's easy: it may be a curl call or a similar feature available in every mainstream language. With web sockets, you can't be sure how long would it take to make a client using [insert the name of a language you don't know yet here].

I've used web sockets in several projects in .NET, Python and node.js.

  • In .NET, it wasn't too difficult, but still, I've still spent a few days trying to figure out some cryptic problems, such as the connection dropped as soon as it is opened. (This was prior to SignalR; I never tried SignalR). I also used WCF in web sockets mode, which wasn't without issues either (but I believe that WCF always comes with issues).

  • In node.js, this was doable, but I had to switch twice the libraries until I've found one which works. I believe I've spent at least a week trying to make a web sockets Hello World.

  • In Python, I tried once, spent two or three days, and abandoned. It never worked.

Compare this to REST: the only problems one can encounter with a new language/framework is to know how to POST files or receive a very large binary response. I remember spending a few hours searching for solutions for some languages. Still, a few hours for a special case is nothing compared to days or weeks for a simple Hello World.

  • 2
    Upvoted your answer, MainMa, as I found it interesting/helpful. There's one point I don't understand though. You mention that a small number of clients is OK to handle over web sockets (e.g., at most 5 at the same time). Then you mention StackOverflow uses web sockets on their homepage. How do they handle such a high number of users? I ask because I am trying 20+ SignalR connections and I find message delays slowly start to inrease, before the entire thing comes crashing down (everything unresponsive). – gnychis Apr 20 '15 at 2:38
  • 1
    @gnychis: there are many solutions for that, but many of them are more related to the infrastructure itself (that is what serverfault.com is for). In general, throw more hardware and split users among domains, so that some connections are handled by sockets1.example.com, others by sockets2.example.com, etc. Quite effective but also quite expensive in terms of hardware and bandwidth. – Arseni Mourzenko Apr 20 '15 at 6:15
  • 3
    This answer is excellent, but I would like to narrow the original question. If an app requires a continuous websocket connection, then why not use websockets entirely in lieu of a REST API? Since a websocket is open, perhaps it should be fully utilized. – HappyNomad May 22 '16 at 0:23
  • I just found an answer to my own question. – HappyNomad May 22 '16 at 2:21
1

Just my 2 cents...

I think it's not really about performance or whatsoever. It's about standards. REST is a standard and IMHO has following advantages:

  • HTTP requests are straightforward to use. Everybody can quickly use a REST API. Heck, you can even open the browser and type an URL to see the data, how more interactive can you be?
  • (Almost) any programming language can use it. It's kind of a universal interface. Interfacing with SignalR from an exotic language seems less obvious.
  • It has nice tooling support, like http://petstore.swagger.wordnik.com/
  • It's a nice "interface" to debug. You can easily monitor incoming and outgoing messages directly in the browser, see the data, etc. With websockets and custom libraries, it's not as obvious, you have to explicitly log everything.
  • 1
    While you make some good points about REST APIs being a little more straightforward and probably having better tooling, this answer says a few things that just aren't true. REST is not a standard, whereas WebSockets is. – StriplingWarrior Feb 23 '18 at 0:06
  • 1
    I guess it was poor wording from my part. What I meant with "standard" is being commonplace, widely used, the default way of doing things... and not "being an RFC Standard". – dagnelies Feb 23 '18 at 8:32
  • Good clarification. And, btw, Chrome at least allows you to see WebSockets traffic in its dev tools. I imagine the other browsers probably do too. – StriplingWarrior Feb 23 '18 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.