8 ms·
uWebSockets: Scalable WebSocket server library for Node.js and C++11
- est 10y agoAnything similar in Python? Currently using pypy+tornado-sockjs. Works OK.
- e12e 10y agoMaybe uvloop? "Uvloop: Fast Python networking" https://news.ycombinator.com/item?id=11625585 https://news.ycombinator.com/item?id=11625585 Maybe paired with Growler: "Growler: Asyncio Micro-Framework in Python" https://news.ycombinator.com/item?id=11632181 https://news.ycombinator.com/item?id=11632181 "Simple websocket server with uvloop.": https://gist.github.com/kracekumar/daf10b3be3191a78b037c0c79667c26c https://gist.github.com/kracekumar/daf10b3be3191a78b037c0c79...
- alexhultman 10y agoNo offence, but I don't think you fully grasp the situation here. This is an extremely optimized fully native server written with low-level CPU awareness. You can absolutely not, in any possible way, write this in Python.
- Thaxll 10y agoBecause Nodejs is known to be highly performant with its single thread model...
- alexhultman 10y agoNode.js has nothing to do with the performance of this server.
- Thaxll 10y agoMy answer was directed to the comment you made about performance for Python and yet the lib you provide has binding for Nodejs which is not a very fast runtime.
- e12e 10y ago"TL;DR asyncio is an asynchronous I/O framework shipping with the Python Standard Library. In this blog post, we introduce uvloop: a full, drop-in replacement for the asyncio event loop. uvloop is written in Cython and built on top of libuv. uvloop makes asyncio fast. In fact, it is at least 2x faster than nodejs, gevent, as well as any other Python asynchronous framework. The performance of uvloop-based asyncio is close to that of Go programs." The question asked was if there is "anything [similar in] python", so there's an obvious requirement of being able to use it from python. That leaves either something with a bit of a friendly python wrapper, or just calling out directly to (only) pure C/C++ code. The latter might be even faster, but at that point it's questionable if calling it from python really is worth the trouble at all. So, I think it's fair to say that "uvloop may be 'something [similar in]' python".
- e12e 10y agoAlthough, thinking a bit more on this (and your more helpful reply to another poster), it might very well be that for web sockets, a better performing solution for python might be to write a wrapper for uWebSockets (the c++ implementation) in python. I'm guessing that the scaffolding code for the websocket-part in python when working with uvloop might indeed give a meaningful performance and/or memory hit (I'm leaning towards memory probably being the most significant difference here). I'd be interesting to compare a python+uvloop websocket implementation and uWS (both using nodejs and c++) -- and at some point see if wrapping uWS for python would make a meaningful difference.
- alexhultman 10y agoWARNING ----> NO OFFENCE: You need to realize, that libuv itself was simply too heavyweight for this project. Think about that statement for a while. This is why I use UNIX syscalls directly, and only use uv_poll_t, not the full-on uv_tcp_t. This is the level of optimizations we are talking about -> when libuv is considered too heavyweight... When libuv becomes too heavyweight to keep up, having this discussion about how a Python async network library could implement similar performance is just purely ridiculous. WARNING -> NO OFFENCE
- barkingdog 10y agoI can understand that you might be a bit frustrated right now, because perhaps that level of performance in pure python may literally be difficult to impossible in this case. But, the question the person was asking was a very reasonable one -- something along the lines of "I'm using this solution in python right now, and I'd like more performance -- what are my options?" It seems like you not only misunderstand the question, but felt the need to question their intelligence and give a rude, vague, and overall unhelpful answer. As a piece of communication, it is overall useless to everyone involved. Please be mindful of the way you come across. There's no need to insult, dismiss and disrespect others. It only takes a single moment, and saves time and energy for both you and them. You could rephrase like "No. You can approach this to a level of <percentage_of_perf>, but it will be hard to pass that point, due to the way the library is written." If you did that, you'd add some very valuable information to the conversation with little effort. It would be a win win for everyone. Beyond that, assuming your benchmarks are accurate, this seems like a prime library for someone to write a python wrapper for! There's autobahn-twisted right now, but I'm not sure how well it performs in comparison.
- ddlerk 10y agoI've actually had run-ins with Alex Hultman before and his tone here seems to follow what I've seen elsewhere. This project looks nice, but I would need to vet it pretty well before I trust it as the lead maintainer continually acts like a child on Reddit and promptly deletes all his comments shortly after. I'm surprised he is on hacker news as he won't be able to delete his juvenile and argumentative comments here.
- alexhultman 10y agoToss a coin and it will land on someones holy ground.. My intentions were not to harm, that was why I said "no offence, but". I cannot more than explain myself. Sorry if I offended anyone (despite explicitly saying "no offence"). Someone should probably censor me, like, a lot.
- barkingdog 10y agoYou've written what potentially appears to be a promising library. Great! In fact, it seems so promising that people are trying to find the equivalent in the language of their choice. Even better! Why not encourage them to write a wrapper for your fine library in their language of choice? Not everyone uses Node, after all. Maybe that person asking for equivalents in Python would've written a binding if you told them "Hey, you could try to do this in pure python but because of the relative performance of my library, you might want to consider writing a binding to µws." I doubt you are trying to harm anyone. But you're not being very helpful. You say that you've "landed on someone's holy ground" but there is a very low chance that is going on. They probably just want to get a job done, and they want to figure out if your tool's a good fit. All it takes is a little bit more thought before you type out a response. I'm not telling you to censor yourself. I'm telling you to stop worrying about explaining yourself, and start thinking about being more helpful. I'm telling you to do it, because it will make things easier for you. You might have written the library, but other people are going to be the ones who use it. They're going to ask you questions, and you're going to think some of those questions are stupid. It's okay. But if you try to be helpful to them even if you think their questions are stupid, you'll spend far less time writing defensive comments on HN, and far more time watching adoption for your library grow, which I assume is something you may want. Best of luck!
- ergo14 10y agoIf it works OK - it works OK :-) I'm using gevent+gevent-websockets.
- alexhultman 10y agoI think the best solution would be to write a Python binding to µWS. You will not be able to implement this perf / memory footprint in Python itself.
- lpinca 10y agoThe project is young but looks promising.
- samsonradu 10y agoI'm currently using the `ws` library for a custom live-streaming solution (broadcasting binary data) and the memory/CPU usage is indeed not small for a handful of clients. What does `uws` bring new (technically) to the table?
- alexhultman 10y agoThere is nothing new brought to the table, feature wise. Same old ws interface, you keep your current code unchanged. Swap require('ws') with require('uws') and see how it works for your code, report any issues if you need them fixed. Well, of course there is a 20-30x perf boost, 10-40x memory improvement compared to ws (as the benchmark table shows).
- samsonradu 10y agoYes, I've seen the very simple integration, I'll definitely give it a try. I was actually curious how you've achieved that performance boost?
- alexhultman 10y agoI get this question quite often, here is a good start: https://github.com/alexhultman/uWebSockets/issues/56 https://github.com/alexhultman/uWebSockets/issues/56
- samsonradu 10y agoCool, hope it's ok for others to read https://www.reddit.com/r/cpp/comments/4ccpsa/%C2%B5websockets_highly_scalable_c11_websocket_server/ https://www.reddit.com/r/cpp/comments/4ccpsa/%C2%B5websocket...
- alexhultman 10y agohttps://www.youtube.com/watch?v=fN1WBgS9u_E https://www.youtube.com/watch?v=fN1WBgS9u_E
- kapouer 10y agoI'm already using it on a socket.io production server. Super-stable for days, and noticeably less cpu / memory usage. Great open source software !
- alexhultman 10y agoYep, thanks for being one of the first adopters :) Like mentioned, it works as an optional engine in Socket.IO, Primus & SocketCluser (in which it will be default in version 5). No code change, swap when you feel lucky :P
- toomim 10y agoI want to use it with SockJS. Do you have any plans or interest in that?
- throwaway2016a 10y agoThis looks awesome. Can I use this with Meteor? If there is any app that would benefit from websocket optimizations it's Meteor.
- alexhultman 10y agoI don't think so but Meatier (https://github.com/mattkrick/meatier https://github.com/mattkrick/meatier) should receive uws as default engine since it build on SC, you could look into that but honestly I don't understand this project at all :P
- throwaway2016a 10y agoNot sure it it helps but it looks like it uses Faye-Websockets https://github.com/faye/faye-websocket-node https://github.com/faye/faye-websocket-node I don't know enough about the inner workings to be able to tell if it's compatible. Any Speeding up of meteor would be HUGE news.
- justsaysmthng 10y agoIn https://github.com/alexhultman/uWebSockets/blob/master/src/uWS.cpp https://github.com/alexhultman/uWebSockets/blob/master/src/u... What's the deal with delete [] (char *) head; where `head` is of type `struct Message` ? Is this some kind of performance trick ?... Otherwise it looks kind of suspicious..
- hendzen 10y agoyeah - the C++ bits were clearly written by someone who doesn't know the language well. I'd be careful about using this code in production. EDIT: Specifically I'm referring to the usage of raw pointers, unchecked pointer arithmetic, goto for flow control and raw new/delete calls. The author says they have run tests under valgrind, but that doesn't say anything unless the inputs were malicious. Ideally it should be compiled with ASAN and run under something like afl-fuzz. Also - why do you take a libuv dependency - then use uv_poll_t directly with raw send/recv calls instead of using uv's provided TCP primitives?
- alexhultman 10y agoIf you allocate the buffer as a char * you should delete it as a char *. Thank you for the kind words.
- alexhultman 10y agoAlso - this server passes the entire Autobahn with no fails, passes Engine.IO tests, Primus tests and exits gracefully with no Valgrind issues. Also, it builds with no warnings. Also, it has been running for weeks stable.
- IIlllIllIIIIlII 10y agoCan I ask why you choose to implement your own queue when many exist within C++? (e.g. using queue<T> or list<T>)
- alexhultman 10y ago
- dhendo 10y agoI'm assuming it's not a straight swap for the `websocket` package? https://github.com/theturtle32/WebSocket-Node https://github.com/theturtle32/WebSocket-Node
- alexhultman 10y agoNope, only ws <-> uws :(
- dhendo 10y agoFair enough. It is probably not a huge rewrite to give it a try.
- jondubois 10y agouWebSockets is bundled as part of SocketCluster http://socketcluster.io/ http://socketcluster.io/ and we plan to make it the default in SC v5. We got a massive speedup! Highly recommended.
- alexhultman 10y agoYes, Socket.IO really need to step up their game if they are going to have this kind of marketing: "FEATURING THE FASTEST AND MOST RELIABLE REAL-TIME ENGINE" Never mind the fact that one libuv tcp stream consumes more memory than one entire WebSocket in µWS...
- spdionis 10y agoThe project looks very good from a technical standpoint and very useful but ... WARNING -> NO OFFENCE ...even linus himself would have a hard time reaching the level of obnoxiousness of this guy. WARNING -> NO OFFENCE
- deleted 10y ago[deleted]
- Matthias247 10y agoHey there. Just wrote down a few things that came to my mind after seeing this. Don't see it as criticism, but as a few hints/remarks what has to be covered by a websocket (or any other protocol) implementation. Imho the high performance part isn't too hard to achieve and shouldn't be the highest rated. The important thing is that such a server should be rock solid in implementation, otherwise it's worthless. Some things that you should answer if you are offering this as a C++ websocket library, and which are currently not covered in the header file: - Whats the threading model of the library? - Will server.run() start a singlethreaded eventloop (I guess so from taking a supershort peek into the code and seeing libuv) and everything is running inside there or will it start multiple worker threads? - Based on the last question, from which thread[s] are the other callbacks called. - If multiple threads are used, is the library threadsafe for sending messages from other threads - Is it integratable in other eventloops? Most applications already have a mainloop or something like this, libraries which only work with their own mainloop are not very useful. Normally applications also have to deal with other application logic besides responding to websocket messages. Besides that a few general questions that you should be able to answer for a websocket implementation: - What's the sending behavior of socket.send? - Will it block until all data was sent? This can cause problems with slow receivers in singlethreaded environments. - Will it copy all data and buffer it internally until it can be sent? This provides no means for backpressure and slow receivers (or non-receivers) can exhaust the servers memory. - Does it handle connection close properly? This is unfortunatly not too easy in websockets. - And are there timers in place for force closing the connection if the shutdown sequence is not completed properly? Or if the initial handshake is not completed in a given timeframe? - Does ist handle control frames? And will it merge control frames (PONGs) if multiple are queued before they are sent? And will it stop sending them after close connection is initiated?
- toomim 10y agoFor your first set of questions: it's single threaded. If you want use multiple processors/threads, you start multiple servers, and either distribute loads with a load balancer or give each one a different TCP port.
- alexhultman 10y ago
- zkhalique 10y agoWhy is your username green?
- Svenskunganka 10y agoNew users have a green username. Not sure when it goes away. You can find posts by green users here: https://news.ycombinator.com/noobstories https://news.ycombinator.com/noobstories
- moron4hire 10y agoYou say you support Windows, but when I try to use it, it gives me an error Error: Compilation of µWebSockets has failed and there is no pre-compiled binary available for your system. Please install a supported C++ compiler and reinstall the module 'uws'. A) Which are the supported compilers? B) This issue makes it seem like that wouldn't matter, anyway? https://github.com/alexhultman/uWebSockets/issues/72 https://github.com/alexhultman/uWebSockets/issues/72
- msim 10y agoIt's code like this that gives C++ a bad reputation. It's not modern in any sense. Compiling it with my default warning level in clang gives 482 warnings! Here's a summary: warning: cast from '...' to '...' increases required alignment from 1 to X [-Wcast-align] warning: declaration shadows a field of '...' [-Wshadow] warning: declaration shadows a local variable [-Wshadow] warning: implicit conversion changes signedness: '...' to '...' [-Wsign-conversion] warning: implicit conversion loses integer precision: '...' to '...' [-Wconversion] warning: implicit conversion loses integer precision: '...' to '...' [-Wshorten-64-to-32] warning: macro name is a reserved identifier [-Wreserved-id-macro] warning: no previous prototype for function '...' [-Wmissing-prototypes] warning: operand of ? changes signedness: 'int' to 'char' [-Wsign-conversion] warning: unused parameter '...' [-Wunused-parameter] warning: use of old-style cast [-Wold-style-cast] Use with caution!
- toomim 10y agoWhy do I care if it's using an "old-style cast" (I presume something like `(float)var` instead of `float(var)`, replacing a reserved identifier with a macro, or contains implicit casts (like `1.0 + 1` instead of `1.0 + float(1)`)? Don't C++ compilers give lots of unimportant warnings?
- alexhultman 10y agoYes, my friend. This guy is trying to roast the library based on bullshit warnings that normal projects (Node.js as one example) explicitly disable. So if you want to make a case out of this, you will have to report this "issue" to Node.js developers also, because they also have a lot of warnings ignored by turning them of, simply because they are pedantic.
- deleted 10y ago[deleted]
- alexhultman 10y agoSo you enabled pedantic warning level, and you got a bunch of pedantic nonsense warnings. There is a reason for these not to be enabled by default. * Unused parameter -> rly? Who gives a damn? * Use of old style cast -> Well I'm old style, get over it. * No previous prototype declaration -> Again, I do this if I want to. * Shadows field -> who cares? No me. * Cast increases required alignment -> Well, obviously the perf cost is not an issue here. * Etc, etc, etc These are pedantic warnings. However, this is an open source prject and you are free to send me PR's whenever you want.
- alexhultman 10y agoI want to thank all people involved in making this open source project possible. Things are by far not set in stone and this library has only been in development for about 2 months now. We are working with SocketCluster to make µWS default in version 5, and I have gotten a lot of help from a lot of people during these months. Thanks for support, I will be accepting PR's and receiving issues that we need to fix before making any kind of official stable release. Also, try to ignore the hateful comments - these commenters build their cases on thin air, and if you actually do find anything you want to change - I will accept PR's that can be shown to improve the library.
- meir_yanovich 10y agoWhat is the main difference between libwebsockets and this ? can it be embedded in to libuv? in C
- alexhultman 10y agoYou can create a C binding and it does integrate with libuv. libwebsockets is targeting the embedded world with a smaller code footprint (libc vs libstdc++). libwebsockets performs very good in memory and CPU time.