Pushpin is a reverse proxy server written in C++ that makes it easy to implement WebSocket, HTTP streaming, and HTTP long-polling services.

Overview

Pushpin

Website: https://pushpin.org/
Chat Room: Join the chat at https://gitter.im/fanout/pushpin

Pushpin is a reverse proxy server written in C++ that makes it easy to implement WebSocket, HTTP streaming, and HTTP long-polling services. The project is unique among realtime push solutions in that it is designed to address the needs of API creators. Pushpin is transparent to clients and integrates easily into an API stack.

How it works

Pushpin is placed in the network path between the backend and any clients:

pushpin-abstract

Pushpin communicates with backend web applications using regular, short-lived HTTP requests. This allows backend applications to be written in any language and use any webserver. There are two main integration points:

  1. The backend must handle proxied requests. For HTTP, each incoming request is proxied to the backend. For WebSockets, the activity of each connection is translated into a series of HTTP requests1 sent to the backend. Pushpin's behavior is determined by how the backend responds to these requests.
  2. The backend must tell Pushpin to push data. Regardless of how clients are connected, data may be pushed to them by making an HTTP POST request to Pushpin's private control API (http://localhost:5561/publish/ by default). Pushpin will inject this data into any client connections as necessary.

To assist with integration, there are libraries for many backend languages and frameworks. Pushpin has no libraries on the client side because it is transparent to clients.

Example

To create an HTTP streaming connection, respond to a proxied request with special headers Grip-Hold and Grip-Channel2:

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 22
Grip-Hold: stream
Grip-Channel: test

welcome to the stream

When Pushpin receives the above response from the backend, it will process it and send an initial response to the client that instead looks like this:

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: Transfer-Encoding

welcome to the stream

Pushpin eats the special headers and switches to chunked encoding (notice there's no Content-Length). The request between Pushpin and the backend is now complete, but the request between the client and Pushpin remains held open. The request is subscribed to a channel called test.

Data can then be pushed to the client by publishing data on the test channel:

curl -d '{ "items": [ { "channel": "test", "formats": { "http-stream": \
    { "content": "hello there\n" } } } ] }' \
    http://localhost:5561/publish

The client would then see the line "hello there" appended to the response stream. Ta-da, transparent realtime push!

For more details, see the HTTP streaming section of the documentation. Pushpin also supports HTTP long-polling and WebSockets.

Example using a library

Using a library on the backend makes integration is even easier. Here's another HTTP streaming example, similar to the one shown above, except using Pushpin's Django library. Please note that Pushpin is not Python/Django-specific and there are backend libraries for other languages/frameworks, too.

The Django library requires configuration in settings.py:

MIDDLEWARE_CLASSES = (
    'django_grip.GripMiddleware',
    ...
)

GRIP_PROXIES = [{'control_uri': 'http://localhost:5561'}]

Here's a simple view:

from django.http import HttpResponse
from django_grip import set_hold_stream

def myendpoint(request):
    if request.method == 'GET':
        # subscribe every incoming request to a channel in stream mode
        set_hold_stream(request, 'test')
        return HttpResponse('welcome to the stream\n', content_type='text/plain')
    ...

What happens here is the set_hold_stream() method flags the request as needing to turn into a stream, bound to channel test. The middleware will see this and add the necessary Grip-Hold and Grip-Channel headers to the response.

Publishing data is easy:

from gripcontrol import HttpStreamFormat
from django_grip import publish

publish('test', HttpStreamFormat('hello there\n'))

Example using WebSockets

Pushpin supports WebSockets by converting connection activity/messages into HTTP requests and sending them to the backend. For this example, we'll use Pushpin's Express library. As before, please note that Pushpin is not Node/Express-specific and there are backend libraries for other languages/frameworks, too.

The Express library requires configuration and setting up middleware handlers before and after any endpoints:

var express = require('express');
var grip = require('grip');
var expressGrip = require('express-grip');

expressGrip.configure({
    gripProxies: [{'control_uri': 'http://localhost:5561', 'key': 'changeme'}]
});

var app = express();

// Add the pre-handler middleware to the front of the stack
app.use(expressGrip.preHandlerGripMiddleware);

// put your normal endpoint handlers here, for example:
app.get('/hello', function(req, res, next) {
    res.send('hello world\n');

    // next() must be called for the post-handler middleware to execute
    next();
});

// Add the post-handler middleware to the back of the stack
app.use(expressGrip.postHandlerGripMiddleware);

Because of the post-handler middleware, it's important that you call next() at the end of your handlers.

With that structure in place, here's an example of a WebSocket endpoint:

app.post('/websocket', function(req, res, next) {
    var ws = expressGrip.getWsContext(res);

    // If this is a new connection, accept it and subscribe it to a channel
    if (ws.isOpening()) {
        ws.accept();
        ws.subscribe('all');
    }

    while (ws.canRecv()) {
        var message = ws.recv();

        // If return value is null then connection is closed
        if (message == null) {
            ws.close();
            break;
        }

        // broadcast the message to everyone connected
        expressGrip.publish('all', new grip.WebSocketMessageFormat(message));
    }

    // next() must be called for the post-handler middleware to execute
    next();
});

The above code binds all incoming connections to a channel called all. Any received messages are published out to all connected clients.

What's particularly noteworthy is that the above endpoint is stateless. The app doesn't keep track of connections, and the handler code only runs whenever messages arrive. Restarting the app won't disconnect clients.

The while loop is deceptive. It looks like it's looping for the lifetime of the WebSocket connection, but what it's really doing is looping through a batch of WebSocket messages that was just received via HTTP. Often this will be one message, and so the loop performs one iteration and then exits. Similarly, the ws object only exists for the duration of the handler invocation, rather than for the lifetime of the connection as you might expect. It may look like socket code, but it's all an illusion. 🎩

For details on the underlying protocol conversion, see the WebSocket-Over-HTTP Protocol spec.

Example without a webserver

Pushpin can also connect to backend servers via ZeroMQ instead of HTTP. This may be preferred for writing lower-level services where a real webserver isn't needed. The messages exchanged over the ZeroMQ connection contain the same information as HTTP, encoded as TNetStrings.

To use a ZeroMQ backend, first make sure there's an appropriate route in Pushpin's routes file:

* zhttpreq/tcp://127.0.0.1:10000

The above line tells Pushpin to bind a REQ-compatible socket on port 10000 that handlers can connect to.

Activating an HTTP stream is as easy as responding on a REP socket:

import zmq
import tnetstring

zmq_context = zmq.Context()
sock = zmq_context.socket(zmq.REP)
sock.connect('tcp://127.0.0.1:10000')

while True:
    req = tnetstring.loads(sock.recv()[1:])

    resp = {
        'id': req['id'],
        'code': 200,
        'reason': 'OK',
        'headers': [
            ['Grip-Hold', 'stream'],
            ['Grip-Channel', 'test'],
            ['Content-Type', 'text/plain']
        ],
        'body': 'welcome to the stream\n'
    }

    sock.send('T' + tnetstring.dumps(resp))

Why another realtime solution?

Pushpin is an ambitious project with two primary goals:

  • Make realtime API development easier. There are many other solutions out there that are excellent for building realtime apps, but few are useful within the context of APIs. For example, you can't use Socket.io to build Twitter's streaming API. A new kind of project is needed in this case.
  • Make realtime push behavior delegable. The reason there isn't a realtime push CDN yet is because the standards and practices necessary for delegating to a third party in a transparent way are not yet established. Pushpin is more than just another realtime push solution; it represents the next logical step in the evolution of realtime web architectures.

To really understand Pushpin, you need to think of it as more like a gateway than a message queue. Pushpin does not persist data and it is agnostic to your application's data model. Your backend provides the mapping to whatever that data model is. Tools like Kafka and RabbitMQ are complementary. Pushpin is also agnostic to your API definition. Clients don't necessarily subscribe to "channels" or receive "messages". Clients make HTTP requests or send WebSocket frames, and your backend decides the meaning of those inputs. Pushpin could perhaps be awkwardly described as "a proxy server that enables web services to delegate the handling of realtime push primitives".

On a practical level, there are many benefits to Pushpin that you don't see anywhere else:

  • The proxy design allows Pushpin to fit nicely within an API stack. This means it can inherit other facilities from your REST API, such as authentication, logging, throttling, etc. It can be combined with an API management system.
  • As your API scales, a multi-tiered architecture will become inevitable. With Pushpin you can easily do this from the start.
  • It works well with microservices. Each microservice can have its own Pushpin instance. No central bus needed.
  • Hot reload. Restarting the backend doesn't disconnect clients.
  • In the case of WebSocket messages being proxied out as HTTP requests, the messages may be handled statelessly by the backend. Messages from a single connection can even be load balanced across a set of backend instances.

Install

Check out the the Install guide, which covers how to install and run. There are packages available for Debian/Ubuntu and Homebrew (Mac), or you can build from source.

If you want to build the git version and have the dependencies installed already, then below are brief build instructions:

# pull submodules
git submodule init && git submodule update

# build
./configure --qtselect=5 && make

# copy default config
cp -r examples/config .

# run!
./pushpin

By default, Pushpin listens on port 7999 and requests are handled by its internal test handler. You can confirm the server is working by browsing to http://localhost:7999/. Next, you should modify the routes config file to route requests to your backend webserver. See Configuration.

Scalability

Pushpin is horizontally scalable. Instances don’t talk to each other, and sticky routing is not needed. Backends must publish data to all instances to ensure clients connected to any instance will receive the data. Most of the backend libraries support configuring more than one Pushpin instance, so that a single publish call will send data to multiple instances at once.

Optionally, ZeroMQ PUB/SUB can be used to send data to Pushpin instead of using HTTP POST. When this method is used, subscription information is forwarded to each publisher, such that data will only be published to instances that have listeners.

As for vertical scalability, Pushpin has been tested reliably with 10,000 concurrent connections running on a single Amazon EC2 m3.xlarge instance. 20,000 connections and beyond are possible with some latency degradation. We definitely want to increase this number, but the important thing is that Pushpin is horizontally scalable which is effectively limitless.

What does the name mean?

Pushpin means to "pin" connections open for "pushing".

License

Pushpin is offered under the GNU AGPL. See the COPYING file.

Footnotes

1: Pushpin can communicate WebSocket activity to the backend using either HTTP or WebSockets. Conversion to HTTP is generally recommended as it makes the backend easier to reason about.

2: GRIP (Generic Realtime Intermediary Protocol) is the name of Pushpin's backend protocol. More about that here.

Comments
  • Brew installation of Pushpin not able to run in MacOS Big Sur

    Brew installation of Pushpin not able to run in MacOS Big Sur

    I setup pushpin using brew on my Mac, but whenever I try to run it, I get the following in my terminal:

    INFO] 2020-11-21 11:59:10.314 starting...
    [INFO] 2020-11-21 11:59:10.315 using config: /usr/local/etc/pushpin/pushpin.conf
    [INFO] 2020-11-21 11:59:10.315 starting condure
    [INFO] 2020-11-21 11:59:10.316 starting zurl
    [INFO] 2020-11-21 11:59:10.317 starting proxy
    [INFO] 2020-11-21 11:59:10.318 starting handler
    [INFO] 2020-11-21 11:59:10.321 started
    [ERR] 2020-11-21 11:59:10.354 handler: Exited unexpectedly
    [INFO] 2020-11-21 11:59:10.355 stopping condure
    [INFO] 2020-11-21 11:59:10.355 stopping zurl
    [INFO] 2020-11-21 11:59:10.355 stopping proxy
    [INFO] 2020-11-21 11:59:10.381 stopped
    

    Sometimes there is a flash of a modal asking to Allow something (I assume incoming port connections), but it disappears before I can click Allow. Any ideas why this is happening and how I might fix it?

    I'm running Big Sur, but since this is my first time trying to run pushpin I'm not sure if that's a contributing factor.

    opened by ericklind 24
  • ERR_INCOMPLETE_CHUNKED_ENCODING

    ERR_INCOMPLETE_CHUNKED_ENCODING

    This error appears in chrome when my app is behind pushpin (in Docker, last ver 1.19.1-1). ERR_INCOMPLETE_CHUNKED_ENCODING It takes a refresh several times to make it disappear, and the site is slower.

    opened by Per0x 18
  • Pushpin not able to start

    Pushpin not able to start

    When i want to start pushpin I am getting following output

    starting...
    starting mongrel2 (http:3000)
    starting m2adapter
    starting zurl
    starting pushpin-proxy
    starting pushpin-handler
    started
    Traceback (most recent call last):
      File "/usr/local/bin/pushpin", line 59, in <module>
        runner.run(exedir, config_file, verbose)
      File "/usr/local/lib/pushpin/runner/runner.py", line 111, in run
        p.wait()
      File "/usr/local/lib/pushpin/runner/processmanager.py", line 90, in wait
        p.check()
      File "/usr/local/lib/pushpin/runner/processmanager.py", line 41, in check
        raise RuntimeError("process exited unexpectedly: %s" % self.name)
    RuntimeError: process exited unexpectedly: m2adapter
    

    I checked mongrel2 and i am able to run it without any kind of issues. I checked m2adapter logs within var/www/pushpin log directory and nothing usefull there:

    [INFO] 2015-04-07 14:08:25.554 starting...
    [INFO] 2015-04-07 14:09:19.096 starting...
    [INFO] 2015-04-07 14:12:22.728 starting...
    [INFO] 2015-04-07 15:06:56.012 starting...
    [INFO] 2015-04-07 19:05:10.023 starting...
    [INFO] 2015-04-07 19:13:03.515 starting...
    [INFO] 2015-04-07 19:15:24.216 starting...
    [INFO] 2015-04-07 19:15:57.014 starting...
    [INFO] 2015-04-07 19:23:19.709 starting...
    [INFO] 2015-04-07 19:28:20.920 starting...
    [INFO] 2015-04-07 19:29:00.137 starting...
    

    Any kind of additional configuration for m2adapter required?

    opened by mersed 16
  • Connection reset when filesize is big

    Connection reset when filesize is big

    I am using hapi as api server. And testing via request.

    test_request.js

    fs.createReadStream('./workbooks/tmp/somefile.csv')
      .pipe(
        request({
          method: 'POST',
          url: 'https://some.domain.com/some_route',
          qs: {
            params: {
              param_a: 'some_param'
            },
            email: '[email protected]',
            prj: 'someprj'
          },
          agentOptions: {
            ca: fs.readFileSync('./ssl/cert.pem')
          }      
        },function(err,response,body){
          if (err) console.log(err);
          console.log(body);
        })
      )
      .on('error', function(err){
        console.log(err.stack);
      });
    

    hapi_route.js

    module.exports = {
      method  : "POST",
      path    : "/some_route",
      config: { 
        auth: false,
        payload: {
          maxBytes: 100*1024*1024,
          output: 'stream'
          parse: false
        }
      },
      handler : handleRoute
    };
    

    I get this error

    Bad Request
    Error: write ECONNRESET
        at errnoException (net.js:905:11)
        at Object.afterWrite (net.js:721:19)
    
    

    if I just send the content as a chunk

    test_request.js

    request({
          method: 'POST',
          url: 'https://some.domain.com/some_route',
          qs: {
            params: {
              param_a: 'some_param'
            },
            email: '[email protected]',
            prj: 'someprj'
          },
          agentOptions: {
            ca: fs.readFileSync('./ssl/cert.pem')
          } ,
         body: fs.readFileSync('somefile.csv')
        },function(err,response,body){
          if (err) console.log(err);
          console.log(body);
        })
    

    hapi_route.js

    module.exports = {
      method  : "POST",
      path    : "/some_route",
      config: { 
        auth: false,
        payload: {
          maxBytes: 100*1024*1024,
          parse: false
        }
      },
      handler : handleRoute
    };
    

    I get this error

    { [Error: socket hang up] code: 'ECONNRESET' }
    

    however, if I try with a smaller file, everything is working fine. I can't seem to find any configuration to control the max payload size in pushpin? I assume there should be some equivalent to nginx's upload_max_filesize??

    opened by eterna2 15
  • SUB to stats socket not working

    SUB to stats socket not working

    The demo Python program (pasted below) that connects to the stats socket and prints the decoded messages is stuck at the sock.recv() and does not print anything, although I can successfully have pushpin play along with clients and origin server. The permissions on the socket look good (srwxr-xr-x 1 pushpin zurl). Am I missing anything? Thanks!

    import sys
    import tnetstring
    import zmq
    
    ctx = zmq.Context()
    sock = ctx.socket(zmq.SUB)
    sock.connect('ipc://var/run/pushpin/pushpin-stats')
    sock.setsockopt(zmq.SUBSCRIBE, '')
    
    while True:
        m_raw = sock.recv()
        mtype, mdata = m_raw.split(' ', 1)
        if mdata[0] != 'T':
            print 'unsupported format'
            continue
        m = tnetstring.loads(mdata[1:])
        print '%s %s' % (mtype, m)
    
    opened by aus70 12
  • mongrel2 exits uncleanly

    mongrel2 exits uncleanly

    Sometimes Pushpin will log a message like this on exit:

    [ERR] 2016-10-22 14:09:37.809 m2 http:7999: Exited uncleanly
    

    This is a bug in Mongrel2 (a dependency of Pushpin), and not Pushpin itself, but since users may see this error I figured it would be good to have an issue filed until it is fixed. Note that the bug is harmless.

    opened by jkarneges 12
  • Unexpected server response: 502

    Unexpected server response: 502

    While going through the Pushpin Crash Course on YouTube, this command:

    wscat --connect ws://localhost:7999/testwebsocket.php

    Generates this error:

    error: Unexpected server response: 502

    This is a fresh server running Apache and it's definitely an Apache config issue. @jkarneges if you can share your Apache setup config that'd be awesome, since the video indicates you're also running Apache.

    opened by frey1esm 11
  • Bintray sunsetting

    Bintray sunsetting

    Howdy,

    While investigating a failure in our build step that installs Pushpin, I found out that Bintray is being sunset; our build failure is because we were attempting to build during a scheduled brownout of the Bintray. I'm opening this issue to bring to your attention that we'll need a new hosting solution soon.

    Thanks much.

    opened by chrisbodhi 10
  • Using Python sortedcontainers vs blist

    Using Python sortedcontainers vs blist

    First, thanks for a great package. I'm exploring real-time Django solutions and am currently evaluating this.

    I noticed that the project is using the Python blist module, in particular the sorteddict data type is used for expiring subs by time. As the author of the sortedcontainers module, I wondered why. SortedContainers is a pure-Python implementation of SortedList, SortedDict, and SortedSet data types. For your use pattern of getting, setting, deleting, and iterating sortedcontainers.SortedDict looks faster than blist.sorteddict. Take a look at the benchmarks at http://www.grantjenks.com/docs/sortedcontainers/performance.html#id2

    But then I noticed that your typical install instructions are a list of Debian packages. And sortedcontainers doesn't have a Debian package (though someone recently requested that (https://github.com/grantjenks/sorted_containers/issues/29) so I wanted to ask:

    1. How did you choose blist?
    2. Is the lack of a Debian package for sortedcontainers a deal breaker?
    3. Would you accept a pull request that changed the dependency and made the code a bit more idiomatic? In particular, I'd be really curious to test any benchmark that might be affected by such a change.

    Thanks for reading.

    opened by grantjenks 10
  • Django WebSocket Browser: connection refused

    Django WebSocket Browser: connection refused

    Got a django endpoint which is working well with an http curl from cli, but connection gets refused when attempting to create a websocket object in browser.

    JS Console in Chrome: var ws = new WebSocket('ws://localhost:7999/dashboard/stream/');

    WebSocket connection to 'ws://localhost:7999/dashboard/stream/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

    enabled the over_http with no luck.

    Django server registers no incoming requests when attempting websocket conn from browser.

    opened by mbhassan 9
  • X-Forwarded-Protocol should actually be X-Forwarded-Proto per RFC7239

    X-Forwarded-Protocol should actually be X-Forwarded-Proto per RFC7239

    So I wasted a few hours debugging why none of my apps that do https redirects were respecting this header... turns out this is the culprit... Per RFC7239 and most common usage (nginx/flask/apache/etc), the header should be X-Forwarded-Proto.

    We have worked around this in our app code for now but it is less than ideal.

    opened by charliewolf 8
  • Memory increasing when clients connect but doesn't free up when they disconnect

    Memory increasing when clients connect but doesn't free up when they disconnect

    I'm seeing something strange with the memory in a pushpin container I have running locally and I'm just trying to understand if it's a bug, intentional behaviour or there's some config I haven't configured properly that's causing it to happen.

    I have a simple Go server with a handler (/stream endpoint) that returns the headers from the docs that are required to implement HTTP Streaming. In front of this server I run a pushpin proxy in a docker container using the fanout/pushpin image. I then have a small Go program that can spin up N clients that make requests to the /stream and wait for events.

    However when I run the program to connect N clients I see that the memory in the pushpin container increases, I assume some sort of buffer is being allocated for the connected clients? But then when these clients disconnect it looks like that memory isn't being free'd up. I've left the container running for a good few minutes and the memory usage doesn't ever seem to decrease but I've included a short video demonstrating what I'm seeing.

    pushpin memory recording.zip

    This is the version of the pushpin docker image that I'm using

    $ docker images | grep fanout/pushpin    
    fanout/pushpin                                                    latest                          f43025c29c42   3 months ago    241MB
    

    Here's a zip with my scripts, docker-compose file and pushpin.conf. To reproduce you can do the following

    // Build the server and client binaries
    make build 
    
    Bring up pushpin container
    // make dev
    
    // Run Go Server
    ./server
    
    // Connect clients
    ./clients --client 1000
    

    puspin-server.zip

    opened by jcox250 5
  • Not able to publish messages via 0MQ from backend server

    Not able to publish messages via 0MQ from backend server

    I have a setup where i have a docker image running the pushpin server and have used configuration from the sample file to configure the server. I am able to get and send messages via http but i am unable to publish back messages to the 0MQ SUB socket. Does the SUB socket also require routes file to have a 0MQ line? Can http and 0MQ be used together i.e. get message to backend via http and send message back to pushpin via 0MQ? I have posted the config used below. Also on the pushpin side i am unable to check if the message from the socket has reached, I have turned on the debug mode but am not able to see any activity.

    [global]
    include={libdir}/internal.conf
    [runner]
    services=condure,zurl,pushpin-proxy,pushpin-handler
    http_port=7999
    [proxy]
    sig_key=value_is_present
    debug=true
    # routes config file (path relative to location of this file)
    routesfile=routes
    # enable debug mode to get informative error responses
    debug=false
    # whether to use automatic CORS and JSON-P wrapping
    auto_cross_origin=false
    [handler]
    # ipc permissions (octal)
    #ipc_file_mode=777
    
    # bind PULL for receiving publish commands
    push_in_spec=tcp://*:5560
    
    # list of bind SUB for receiving published messages
    push_in_sub_spec=tcp://0.0.0.0:5562
    
    # whether the above SUB socket should connect instead of bind
    push_in_sub_connect=false
    
    # addr/port to listen on for receiving publish commands via HTTP
    push_in_http_addr=0.0.0.0
    push_in_http_port=5561
    
    opened by shreyasdn 4
  • Schema of the architecture of pushpin ?

    Schema of the architecture of pushpin ?

    Hello, i use pushpin for the https://github.com/tracim/tracim project.

    As we get multiple log un pushpin related to the multiples components of it. It's a bit complicated to clearly understand what it mean. A schema giving explaination of the process (the goal of conduire, zurl, mongrel2, pusphin-handler, etc...), will be useful.

    Is there already something like this ?

    Thanks for pushpin, it's an awesome software !

    opened by inkhey 1
  • intergate a small backend server with existing pushpin Docker file

    intergate a small backend server with existing pushpin Docker file

    Running pushpin Docker as a container works fine as standalone. Now i am trying to add a small nodejs banckend application to the existing pushpin Dockerfile so that i can set headers and also acts as a reverse proxy for pushpin. but as the Dokcerfile has the limitation of single CMD command i cannot run the node server command once again in the same Dockerfile. eg: CMD ["pushpin", "--merge-output"]. how can i solve this.

    opened by bharath-naik 3
  • Respond to websocket pings

    Respond to websocket pings

    It would be nice if Pushpin could automatically respond to ping messages rather than forwarding to the backend. Ideally this would work for not just literal PING frames, but also TEXT frames with ping-like content. Messages not considered to be pings should still be forwarded to the backend for handling.

    opened by jkarneges 1
Owner
Fanout
Powering streaming APIs
Fanout
reverse proxy with web server and preview page

Reverse Proxy Dependencies Go Make Suport Termux (android/afsd kernel) linux (kernel) Install: Termux: 1 step: Install Go-lang, Git and Make pkg insta

AlbâniaSecurity-RT 9 Dec 8, 2022
BingBing 60 Dec 15, 2022
zrp is a nat-passthrough reverse proxy written in modern c++.

zrp is a nat-passthrough reverse proxy written in modern c++. A major use case is to expose a local server via a remote server with public IP.

Coleman 12 Oct 27, 2022
Cross-platform, efficient, customizable, and robust asynchronous HTTP/WebSocket server C++14 library with the right balance between performance and ease of use

What Is RESTinio? RESTinio is a header-only C++14 library that gives you an embedded HTTP/Websocket server. It is based on standalone version of ASIO

Stiffstream 924 Jan 6, 2023
Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution

CppServer Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and

Ivan Shynkarenka 958 Jan 3, 2023
websocket and http client and server library, coming with ws, a command line swiss army knife utility

Hello world IXWebSocket is a C++ library for WebSocket client and server development. It has minimal dependencies (no boost), is very simple to use an

Machine Zone, Inc. 369 Jan 5, 2023
Phorklift is an HTTP server and proxy daemon, with clear, powerful and dynamic configuration.

Phorklift is an HTTP server and proxy daemon, with clear, powerful and dynamic configuration.

null 43 Mar 1, 2022
Mongoose Embedded Web Server Library - a multi-protocol embedded networking library with TCP/UDP, HTTP, WebSocket, MQTT built-in protocols, async DNS resolver, and non-blocking API.

Mongoose - Embedded Web Server / Embedded Networking Library Mongoose is a networking library for C/C++. It implements event-driven non-blocking APIs

Cesanta Software 9k Jan 1, 2023
LAppS - Lua Application Server for micro-services with default communication over WebSockets. The fastest and most vertically scalable WebSockets server implementation ever. Low latency C++ <-> Lua stack roundtrip.

LAppS - Lua Application Server This is an attempt to provide very easy to use Lua Application Server working over WebSockets protocol (RFC 6455). LApp

null 48 Oct 13, 2022
cuehttp is a modern c++ middleware framework for http(http/https)/websocket(ws/wss).

cuehttp 简介 cuehttp是一个使用Modern C++(C++17)编写的跨平台、高性能、易用的HTTP/WebSocket框架。基于中间件模式可以方便、高效、优雅的增加功能。cuehttp基于boost.asio开发,使用picohttpparser进行HTTP协议解析。内部依赖了nl

xcyl 29 Dec 17, 2022
A Nginx module which tries to implement proxy wasm ABI in Nginx.

Status This library is under construction. Description A Nginx module which tries to implement proxy wasm ABI in Nginx. Install dependencies Download

API7 104 Dec 29, 2022
An easy to use and powerful open source websocket library written in C.

libwebsock Easy to use C library for websockets This library allows for quick and easy development of applications that use the websocket protocol, wi

Jonathan Hall 47 Nov 13, 2022
WSServer is a fast, configurable, and extendable WebSocket Server for UNIX systems written in C (C11).

WSServer a C WebSocket Server WSServer is a fast, configurable, and extendable WebSocket Server for UNIX systems written in C (C11). As of version 2.0

Morten Houmøller Nygaard 170 Dec 8, 2022
A collection of C++ HTTP libraries including an easy to use HTTP server.

Proxygen: Facebook's C++ HTTP Libraries This project comprises the core C++ HTTP abstractions used at Facebook. Internally, it is used as the basis fo

Facebook 7.7k Jan 4, 2023
H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server

H2O - an optimized HTTP server with support for HTTP/1.x, HTTP/2 and HTTP/3 (experimental) Copyright (c) 2014-2019 DeNA Co., Ltd., Kazuho Oku, Tatsuhi

H2O 10.2k Dec 30, 2022
Small and fast cross-platform networking library, with support for messaging, IPv6, HTTP, SSL and WebSocket.

frnetlib Frnetlib, is a cross-platform, small and fast networking library written in C++. There are no library dependencies (unless you want to use SS

Fred Nicolson 23 Nov 25, 2022
HTTP and WebSocket built on Boost.Asio in C++11

HTTP and WebSocket built on Boost.Asio in C++11 Branch Linux/OSX Windows Coverage Documentation Matrix master develop Contents Introduction Appearance

Boost.org 3.6k Jan 4, 2023
Simple embeddable C++11 async tcp,http and websocket serving.

net11 Simple embeddable C++11 async tcp,http and websocket serving. What is it? An easily embeddable C++11 networking library designed to make buildin

Jonas Lund 9 Mar 28, 2020
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

Welcome! The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design

Microsoft 7.2k Dec 30, 2022