16 ms·
Libwebsockets a powerful and lightweight pure C library
- dpflan 5y agoHas anyone used this in a multithreaded implementation, and how is/was the experience?
- Galanwe 5y agoI used to roll my own code for websockets since the protocol is so simple. Switched to libwebsockets when I had to support TLS since I did not wanted to fiddle with openssl directly. Overall the experience was good. It's simple, to the point. Configuration of the library is a bit like dark magic though, not much documentation. > Has anyone used this in a multithreaded implementation It's an event loop based library, so the point is more to have a single asynchronous main thread that fetches the messages, which you can dispatch to threads for processing if you wish.
- vlovich123 5y agoHave you tried libkj? It’s the c++ runtime that underpowers Cap’n’proto’s RPC layer as well as Cloudflare Workers. Has many of the same features - curious how you find the documentation. Disclaimer: I work at Cloudflare.
- Galanwe 5y agoI would love to, but I stopped bothering with C++ a long time ago, and just use C nowadays :-)
- clappski 5y ago>I did not wanted to fiddle with openssl directly It's actually fairly simple to use openssl directly if you have a good handle of sockets in general, it's basically just a case of doing some initialisation and using SSL_write/SSL_read in place of whatever write/read functions you were using before to write to the socket
- nurettin 5y agoYes, you run it on its own thread and output messages to a threadsafe queue for other threads to consume as is the usual practice. Or did you ask for something else?
- winrid 5y agoYou can just fork multiple threads that are each their own server, and then do communication over thread safe queues to workers in other threads.
- ncann 5y agoI have used this library before, it's a powerful library indeed but the documentation is a bit lacking. There isn't a straightforward guide to do the most common operations, even the most simple ones like connecting a client to a server, and you're left with studying the various examples provided, each of them do things a little differently. There are also a lot of undocumented functions/constants/structs.
- ricardo81 5y agoI've also used it on occasion and would agree the documentation is patchy in some areas thought getting a running example is fairly trivial. e.g. when a TLS cert is renewed/replaced, how to deal with that in an already running websocket.
- deleted 5y ago[deleted]
- krona 5y agohttps://libwebsockets.org/git/libwebsockets/tree/minimal-examples/http-client/minimal-http-client/minimal-http-client.c https://libwebsockets.org/git/libwebsockets/tree/minimal-exa... I'd prefer this well written and working minimal example (one of many) to API documentation 99 times out of 100.
- letsgotothemoon 5y agoCheck out the "Secure Streams" of libwebsockets, it hides details of protocols specifics stuff (in the JSON policy) and easier to program network application (just deal with the abstracted states and payload in the callbacks). https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/secure-streams https://libwebsockets.org/git/libwebsockets/tree/minimal-exa... https://libwebsockets.org/git/libwebsockets/tree/lib/secure-streams https://libwebsockets.org/git/libwebsockets/tree/lib/secure-...
- unquietcode 5y agoThis really needs to be a system library; I'm rooting for it.
- iFire 5y agoI wish there was something like this for WebRTC data channels.
- cylon13 5y agoThere is this[0]. It’s C++ but the API is simple and it works well, you don’t need to setup any extra ICE/TURN/STUN stuff either. [0] https://github.com/seemk/WebUDP https://github.com/seemk/WebUDP
- porsager 5y agoThere is - https://github.com/paullouisageneau/libdatachannel https://github.com/paullouisageneau/libdatachannel
- baybal2 5y agoI remember hearing about it many years ago, and am surprised to find it alive, and well now. I always felt that the web people were never about performance, since there were many "pure C" webdev attempts before without much success. Nginx can very realistically handle 1-2M requests per minute on commodity hardware, and no customisation, and that's from the disk. Were somebody really serious about web performance, I think going from millions of requests per minute, to millions of requests per second is 100% possible. I worked on this problem around 6 years ago, when I had a task of squeezing HTTP, and network perf on some API servers close to hardware limits. The task was mostly about gluing DPDK to popular software: nginx, memcached, postgres. I am very enthusiastic to see Libwebsockets getting glib support. Glib is a one of a kind piece of software in the C ecosystem with which you can adopt modern programming methods, and in general approach it as you do it in a big "platform" like environment like NODEJS. Glib is really undeserving neglected, and overlooked.
- staybythebay22 5y agoCoding big web backends in C is extremely expensive. I'm not sure it's worth the tradeoff for most use cases
- baybal2 5y agoI am not talking about whole backends, but task specific individual APIs, especially for performance sensitive tasks.
- danielheath 5y agoYou can get within 20% the performance for 1/10th the cost by using a modern fast language (rust, d, nim, go), and within 50% for even cheaper by using c# or java.
- baybal2 5y agoI really doubt. Of my short encounter with "modern" webdev, I found that running out of RAM was far faster than running out of CPU, even with every trick possible thrown to increase GC aggressiveness. RAM is by far more discriminately priced on all these new "cloud" hostings, and has the most unpredictable performance change with size. Even on real hardware, going for high RAM servers is quite expensive. While CPU, or I/O saturation naturally throttles itself, RAM exhaustion is rarely pretty, and hard to proof your software against. Most disconcerting about this is that your RUST, GO, or the TRUE ENTERPRISE JAVA®, don't really use that RAM at all. Most of "modern languages" RAM content is just zeroes, and empty buffers.
- PaulDavisThe1st 5y agoWe use libwebsockets in Ardour (a cross-platform digital audio workstation) to provide the ability to create control surfaces (GUIs) within the browser. We mostly treat it as a transport layer for OSC messages, which could otherwise be transferred via UDP (if the endpoint wasn't a browser).
- meowface 5y agoSomething close to UDP APIs for browsers (QuicTransport + datagram extension) was in development for a while but the proposal ended up getting rejected/withdrawn.
- willbudd 5y agoI wrote something similar, except instead of providing a library (which Libwebsockets already does a fine job of), I created a server/framework accepting shared objects as backend plugins running as dedicated threads interacting with spsc lockless ringbuffers. In other words, more or less the inverse of a library: https://github.com/wbudd/ringsocket https://github.com/wbudd/ringsocket I haven't been putting much time into it anymore lately, but I intend to create a bunch of language bindings for it soon so you can write plugins in other languages too such as Python, C++, Rust, etc. Should be interesting.
- porsager 5y agoHow does this fare compared to uWebSockets? https://github.com/uNetworking/uWebSockets https://github.com/uNetworking/uWebSockets
- kreetx 5y agouWebSockets appears to be significantly faster, but this one is second: https://github.com/uNetworking/uWebSockets/blob/master/misc/websocket_lineup.png https://github.com/uNetworking/uWebSockets/blob/master/misc/... (linked from uWebSockets main github)
- johnnyApplePRNG 5y agouWebSockets does not have a websocket client interface.
- zarzavat 5y agoIf the maintainer is sane, then that would be one advantage over uwebsockets.
- gemakelijk 5y agoLike most websocket library, uWebSockets works by calling some sort of send/write function. You give the data you want to send, which is a sequence (a string or a vector). The underlying library will take care of buffering that, and the size of that buffer is unbounded. In most of them there is no way to know how much is buffered. But with libwebsocket, it will call a callback written by you, it will call it every time it is ready to send. And then you have to call a write function that does not guarantee you it will write the whole buffer you give it. This can be useful for web based games, you keep the last version of the position of each object, and send them one by one when the client is ready to receive. The memory usage will then be bounded to: size of message * number of objects + number of players (each player can have a message that is currently kept in memory until it is entirely sent, since multiple calls to the callback may be required to send a whole message. The libwebsocket site claims that it is the receiving side that decides when it is ready to send. I don't know exactly how it is determined but I think the sender uses TCP ACKs, the window size...
- Subsentient 5y agoI personally prefer QtWebSockets. I've used libwebsockets before, but I found the API error prone and crusty, and ended up eventually converting it to QWebSockets. That turned out to be a good move.
- fasteo 5y agoNot a library [1], but trivial to integrate in your architecture. Just redirect stdout to gwsocket [1] https://gwsocket.io/ https://gwsocket.io/
- seanieb 5y agoWhen will people stop writing C? The memory safety issues make go, rust etc. much better solutions.
- PartiallyTyped 5y agoC is effectively a _predictable_ and portable assembler. You can't do that with Rust because everything is catastrophically moved, which makes it harder for humans to predict emitted code, and Go afaik has a runtime.
- pjmlp 5y agoPreditable when code is either compiled with -O0 or the target CPU is a PDP-11 clone.
- PartiallyTyped 5y agoLinus seems to disagree with you. Albeit old http://www.youtube.com/watch?v=MShbP3OpASA&t=20m45s http://www.youtube.com/watch?v=MShbP3OpASA&t=20m45s It remains true. Rust uses references all over the place and reuses the same memory addresses within stack that once belonged to another object because the compiler can guarantee it, but that makes it much less reasonable to write. If you can reason with -O0 you can take it that your code will remain correct in later levels.
- pjmlp 5y agoI don't care what Linus thinks, I also happen to disagree with him in regards to C++ and NVidia. > If you can reason with -O0 you can take it that your code will remain correct in later levels. Unless you happen to be a Jedi master in UB performance optimizations, auto-vectorization, OMP, out of line code execution, I very much doubt that.
- bregma 5y agoWhen the entire OS is written entirely in Rust or Go from the kernel on up, and all applications are also written in the same language. Oh, and the silicon itself becomes adapted to the paradigms presented by those programming languages, since C was designed to work on the existing silicon. Forcing entirely new hardware designs to meet an evolving and always-changing software paradigm is an expensive proposition in a commodity market and it will take either a lot of central control and will power or a lot of time.
- mkl95 5y agoHow does performance compare to a C/C++ UDP implementation?